如何在Python中使用子进程重定向输出?

cat*_*ode 87 python subprocess

我在命令行中做了什么:

cat file1 file2 file3 > myfile
Run Code Online (Sandbox Code Playgroud)

我想用python做什么:

import subprocess, shlex
my_cmd = 'cat file1 file2 file3 > myfile'
args = shlex.split(my_cmd)
subprocess.call(args) # spits the output in the window i call my python program
Run Code Online (Sandbox Code Playgroud)

Rya*_*son 237

要回答原始问题,要重定向输出,只需将参数的打开文件句柄传递stdoutsubprocess.call:

# Use a list of args instead of a string
input_files = ['file1', 'file2', 'file3']
my_cmd = ['cat'] + input_files
with open('myfile', "w") as outfile:
    subprocess.call(my_cmd, stdout=outfile)
Run Code Online (Sandbox Code Playgroud)

但正如其他人所指出的那样,cat为此目的使用外部命令是完全无关紧要的.

  • 这是正确的答案,而不是标记为正确的答案. (40认同)
  • 当使用Python的shell时,这应该是管道的一般问题的答案 (6认同)
  • 对于Python 3.5+,使用`subprocess.run(my_cmd,stdout = outfile)`替换`subprocess.call(...)` (4认同)
  • 值得注意的是,如果自定义文件对象没有 fileno 字段(如果它们不是真正的文件),则这不适用于自定义文件对象。 (2认同)

Mar*_*tos 20

更新:不鼓励使用os.system,尽管仍然可以在Python 3中使用.


用途os.system:

os.system(my_cmd)
Run Code Online (Sandbox Code Playgroud)

如果你真的想使用子进程,这里的解决方案(主要是从子进程的文档中提取):

p = subprocess.Popen(my_cmd, shell=True)
os.waitpid(p.pid, 0)
Run Code Online (Sandbox Code Playgroud)

OTOH,你可以完全避免系统调用:

import shutil

with open('myfile', 'w') as outfile:
    for infile in ('file1', 'file2', 'file3'):
        shutil.copyfileobj(open(infile), outfile)
Run Code Online (Sandbox Code Playgroud)

  • `os.system`出现在`subprocess`之前.前者是后者打算替换的遗留API. (12认同)
  • @catatemypythoncode:你不应该使用`os.system()`或`shell = True`.要重定向子进程的输出,请使用`stdout`参数,如[Ryan Thompson的答案](http://stackoverflow.com/a/6482200/4279)所示.虽然在您的情况下您不需要子进程(`cat`),但您可以使用纯Python连接文件. (3认同)
  • OTOH =另一方面 (3认同)

Sin*_*ion 5

@PoltoS 我想加入一些文件,然后处理生成的文件。我认为使用 cat 是最简单的选择。有没有更好的/pythonic方法来做到这一点?

当然:

with open('myfile', 'w') as outfile:
    for infilename in ['file1', 'file2', 'file3']:
        with open(infilename) as infile:
            outfile.write(infile.read())
Run Code Online (Sandbox Code Playgroud)