蟒蛇subprocess.call和管道

蟒蛇subprocess.call和管道

问题描述:

我有,我想使用subprocess.call执行一系列shell命令的脚本,但似乎有在执行时省略了一些命令。蟒蛇subprocess.call和管道

具体来说:

#!/usr/bin/python 
import tempfile 
import subprocess 
import os 
import re 


grepfd, grepfpath = tempfile.mkstemp(suffix=".xx") 
sedfd, sedfpath = tempfile.mkstemp(suffix=".xx") 

# grepoutfile = open(grepfpath, 'w') 
sedoutfile = open(sedfpath, 'w') 

subprocess.call(['cp','/Users/bobby/Downloads/sample.txt', grepfpath]) 

sedcmd = [ 'sort', 
      grepfpath, 
      '|', 
      'uniq', 
      '|', 
      'sed', 
      '-e', 
      '"s/bigstring of word/ smaller /"', 
      '|', 
      'column', 
      '-t', 
      '-s', 
      '"=>"' ] 

print "sedcmd = ", sedcmd 
subprocess.call(['ls', grepfpath ]) 
subprocess.call(['sort', '|', 'uniq' ], stdin = grepfd) 
subprocess.call(sedcmd, stdout = sedoutfile) 

而且它生成此作为输出:

蟒d3.py

sedcmd = [ '排序',在/ var /文件夹/ 3H/_0xwt5bx0hx8tgx06cmq9h_4f183ql/T/tmp5Gp0ff.xx ' '|', 'uniq的', '|', 'sed的', '-e', ' “S /字的bigstring /小/”', '|', '列',' -t ”, '-S', ' “=>”'] /var/folders/3h/_0xwt5bx0hx8tgx06cmq9h_4f183ql/T/tmp5Gp0ff.xx 排序:打开失败:|:没有这样的文件或目录
排序:无效选项 - 电子 尝试`排序--help”以获取更多信息。

第一个'sort:open failed:|:没有这样的文件...来自第一个子进程调用['sort','|','uniq'],stdin = grepfd) 'sort:invalid选项 - e ..来自第二个子进程调用(sedcmd)。

我已经看到了很多,在这种情况下使用管道的例子 - 所以我在做什么错?
谢谢!

+0

如果你想使用shell功能,如管道,你会需要传递一个字符串(不是列表)并设置'shell = True'。详情请阅读'subprocess'文件。 – larsks

这是将运行与管的任意数量的命令一类:

pipeline.py

import shlex 
import subprocess 

class Pipeline(object): 
    def __init__(self, command): 
     self.command = command 
     self.command_list = self.command.split('|') 
     self.output = None 
     self.errors = None 
     self.status = None 
     self.result = None 

    def run(self): 
     process_list = list() 
     previous_process = None 
     for command in self.command_list: 
      args = shlex.split(command) 
      if previous_process is None: 
       process = subprocess.Popen(args, stdout=subprocess.PIPE) 
      else: 
       process = subprocess.Popen(args, 
              stdin=previous_process.stdout, 
              stdout=subprocess.PIPE) 
      process_list.append(process) 
      previous_process = process 
     last_process = process_list[-1] 
     self.output, self.errors = last_process.communicate() 
     self.status = last_process.returncode 
     self.result = (0 == self.status) 
     return self.result 

该实施例显示了如何使用类:

harness.py

from pipeline import Pipeline 

if __name__ == '__main__': 
    command = '|'.join([ 
     "sort %s", 
     "uniq", 
     "sed -e 's/bigstring of word/ smaller /'", 
     "column -t -s '=>'" 
    ]) 
    command = command % 'sample.txt' 
    pipeline = Pipeline(command) 
    if not pipeline.run(): 
     print "ERROR: Pipeline failed" 
    else: 
     print pipeline.output 

我创造了这个示例文件来进行测试:

sample.txt的

word1>word2=word3 
list1>list2=list3 
a>bigstring of word=b 
blah1>blah2=blah3 

输出

a  smaller b 
blah1 blah2  blah3 
list1 list2  list3 
word1 word2  word3 

因此,如果某个命令要使用shell管道可以添加壳=真在子: 所以这将是这样的:

sedcmd = 'sort /var/folders/3h/_0xwt5bx0hx8tgx06cmq9h_4f183ql/T/tmp5Gp0ff.xx | uniq | sed -e "s/bigstring of word/ smaller /" | column -t -s "=>" ' 
subprocess.call(sedcmd, shell=True) 

但要小心与壳=真,这是极力劝阻使用它:subprocess official documentation

所以,如果你想使用管道无壳=真可以在标准输出使用subprocees.PIPE,这里是如何做到这一点的例子:stackoveflow answer