蟒蛇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)。
我已经看到了很多,在这种情况下使用管道的例子 - 所以我在做什么错?
谢谢!
这是将运行与管的任意数量的命令一类:
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
如果你想使用shell功能,如管道,你会需要传递一个字符串(不是列表)并设置'shell = True'。详情请阅读'subprocess'文件。 – larsks