【问题标题】:Pipe result from subprocess to unix sort管道结果从子进程到 unix 排序
【发布时间】:2015-03-11 19:07:25
【问题描述】:

我正在从 python 调用外部 txt 文件的 perl 脚本,并将输出打印到输出文件。但相反,我想将输出通过管道传输到 unix 的排序。现在我不是管道,而是首先编写 perl 程序的输出,然后将我的代码组合在 this stackoverflow answer 下。

import subprocess
import sys
import os

for file in os.listdir("."):

    with open(file + ".out", 'w') as outfile:
        p = subprocess.Popen(["perl", "pydyn.pl", file], stdout=outfile)
        p.wait()

【问题讨论】:

  • 您使用的 python 不正确。如果你要调用很多外部进程(比如排序),而不是使用 python 模块,最好使用 bash、ipython 或其他 shell。
  • 您也可以通过管道输出结果 p = subprocess.Popen("perl pydyn.pl %s | sort" % file, stdout=outfile,shell=True),但为此您必须使用 shell=True 这不是一个好习惯

标签: python subprocess piping


【解决方案1】:

模拟 shell 管道:

#!/usr/bin/env python
import pipes
import subprocess

pipeline = "perl pydyn.pl {f} | sort >{f}.out".format(f=pipes.quote(filename))
subprocess.check_call(pipeline, shell=True)

无需在 Python 中调用 shell:

#!/usr/bin/env python
from subprocess import Popen, PIPE

perl = Popen(['perl', 'pydyn.pl', filename], stdout=PIPE)
with perl.stdout, open(filename+'.out', 'wb', 0) as outfile:
    sort = Popen(['sort'], stdin=perl.stdout, stdout=outfile)
perl.wait() # wait for perl to finish
rc = sort.wait() # wait for `sort`, get exit status

【讨论】:

    【解决方案2】:

    只需使用 bash。使用 python 只会增加你不需要的复杂度。

    for file in $( ls); 
    do 
        perl pydyn.pl $file | sort
    done
    

    上面是一个快速而肮脏的例子,在解析方面更好的选择如下:

    ls | while read file; do perl pydyn.pl "$file" | sort; done
    

    【讨论】:

    • 它在第一个名称中有空格的文件上失败
    • 这可能是由多种原因造成的。我添加了另一个可能会解决问题的示例。
    • 不正确。它应该是read file,而不是read $filebash静默跳过此类错误。 The Zen of Python: “错误永远不应该悄悄地过去。除非明确地沉默。”
    【解决方案3】:

    既然你在 python 中问过这个问题,你也可以通过管道输出结果

    p = subprocess.Popen("perl pydyn.pl %s | sort" % file, stdout=outfile,shell=True) 
    

    但是为此,您必须将其设为shell=True,这不是一个好习惯

    这是一种不成功的方法shell=True

      p = subprocess.Popen(["perl", "pydyn.pl", file], stdout=subprocess.PIPE)
      output = subprocess.check_output(['sort'], stdin=p.stdout,stdout=outfile)
      p.wait()
    

    【讨论】:

    • check_output 此处不正确;你不能改变stdout。如果file 包含空格或$ 等,则"%s" % file 中断,例如,它允许执行任意命令。您应该关闭 p.stdout 以进行适当的清理。见my answer
    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多