简体   繁体   English

os.system的行为与raw_input()和file.readlines()的输入不同

[英]os.system behaves differently w/ input from raw_input() vs file.readlines()

I am running a command through os.system and can get the command needed in two different ways; 我正在通过os.system运行命令,可以通过两种不同的方式获取所需的命令。 from user input or from a file. 从用户输入或从文件。

# 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] 

If I now print filename I get exactly the same output. 如果现在打印文件名,则会得到完全相同的输出。 However when filename is passed through os.system it only works in the top case. 但是,当文件名通过os.system传递时,它仅适用于大写字母。 The other case prints some data I did not ask for. 另一种情况是打印一些我不要求的数据。 I would post full source code but the files are huge! 我会发布完整的源代码,但是文件很大! Here is the a snippit. 这是一个摘录。

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

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

Current Behavior 当前行为

readlines() returns lines with \\n on the end of them. readlines()返回末尾带有\\n行。 Thus, you're splitting the code you run into two separate commands. 因此,您将运行的代码分成两个单独的命令。 Assuming your file is unsorted_input.txt , then, this would run: 假设您的文件是unsorted_input.txt ,那么它将运行:

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

...thus, it writes the output of sort to stdout, and truncates orderedfile.txt to be empty. ...因此,它将sort的输出写入stdout,并截断orderedfile.txt为空。

The smallest possible fix is just to trim the trailing newline from the filename -- but that leaves you open to lots of other bugs: Filenames with spaces, filenames with literal quotes, filenames with command substitutions or combinations thereof will throw the original approach into chaos. 最小的修复方法是从文件名中删除尾随的换行符-但这会使您面临许多其他错误:带空格的文件名,带文字引号的文件名,带命令替换的文件名或其组合将使原始方法陷入混乱。


Preferred Approach (No Shell Required) 首选方法(无需外壳)

A correct implementation would look more like: 正确的实现看起来更像是:

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',
)

Preferred Approach (Safe Shell Usage) 首选方法(安全使用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)

Note in this case that we're passing filenames out of band from code, and quoting the expansions where they're used. 请注意,在这种情况下,我们将文件名从代码中带外传递,并引用使用它们的扩展名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM