我正在通过os.system运行命令,可以通过两种不同的方式获取所需的命令;来自用户输入或文件。

# Code works fine with this
filename = raw_input('Enter a filename:' )

# but it doesn't work if I do this:
f = open("userinput.txt").readlines()
filename = f[1]


如果现在打印文件名,则会得到完全相同的输出。但是,当文件名通过os.system传递时,它仅适用于大写字母。另一种情况是打印一些我不要求的数据。我会发布完整的源代码,但是文件很大!这是一个摘录。

string = "sort -n -k3,3 -k2,2 -k1,1 < "
string1 = "> orderedfile.txt"

cmd = string + filename + string1
reordering = os.system(cmd)

最佳答案

当前行为

readlines()返回末尾带有\n的行。因此,您将运行的代码分为两个单独的命令。假设您的文件是unsorted_input.txt,那么它将运行:

sort -n -k3,3 -k2,2 -k1,1 < unsorted_input.txt
> orderedfile.txt


...因此,它将sort的输出写入stdout,并截断orderedfile.txt为空。

最小的修复方法是从文件名中删除尾随的换行符-但这会使您面临许多其他错误:带空格的文件名,带文字引号的文件名,带命令替换的文件名或其组合将使原始方法陷入混乱。



首选方法(无需外壳)

正确的实现看起来更像是:

import subprocess

def sort_file(input_filename, output_filename):
    subprocess.call(['sort', '-n', '-k3,3', '-k2,2', '-k1,1'],
                    stdin=open(input_filename, 'r'),
                    stdout=open(output_filename, 'w'))

sort_file(
    open('userinput.txt', 'r').readlines()[1].rstrip('\n'),
    'output_file.txt',
)


首选方法(安全使用Shell)

def sort_file(input_filename, output_filename):
    subprocess.call(
        ['sort -n -k3,3 -k2,2 -k1,1 <"$1" >"$2"', # this is the shell script to run
         '_',                                     # this becomes $0 when that script runs
         input_filename,                          # this becomes $1
         output_filename],                        # this becomes $2
        shell=True)


请注意,在这种情况下,我们将文件名从代码中带外传递,并引用使用它们的扩展名。

关于python - os.system的行为与raw_input()和file.readlines()的输入不同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45716845/

10-11 11:57