我试图启动几个bash例程 来自基于GUI的软件。我面临的问题是管道问题。 这里是测试bash脚本( bashScriptTest.sh ):
#!/bin/bash
#---------- Working
ls | sort | grep d > testFile.txt
cat testFile.txt
#---------- NOT working
echo $RANDOM > testFile2.txt
for i in `seq 1 15000`; do
echo $RANDOM >> testFile2.txt
done
awk '{print $1}' testFile2.txt | sort -g | head -1
这里是创建错误的python脚本:
import subprocess
#
with open('log.txt','w') as outfile:
CLEAN=subprocess.Popen("./bashScriptTest.sh", stdout=outfile, stderr=outfile)
print CLEAN.pid
OUTSEE=subprocess.Popen(['x-terminal-emulator', '-e','tail -f '+outfile.name])
从运行python脚本可以看出,遇到了Broken-pipe错误 不是在前三个管道(第一行),而是在awk完成的巨大工作之后。 我需要在bash中管理大量的例程和子例程 并且还使用shell == True标志不会改变一个东西。 我试图用最pythonic的方式写一切,但不幸的是没有 我可以在python中重写所有管道步骤。 另一件需要提及的是,如果您在终端内测试bash脚本 一切正常。 任何帮助将非常感激。提前谢谢!
编辑1:
包含错误的日志文件显示:
bashScriptTest.sh
log.txt
stack.txt
testFile2.txt
test.py
3
sort: write failed: standard output: Broken pipe
sort: write error
答案 0 :(得分:1)
好的,所以这有点模糊,但恰巧我在前一段时间研究question on the python-tutor mailing list时遇到了类似的问题。
在通过子进程模块(在python中)直接运行脚本时,您看到不同行为的原因是,python会覆盖所有子进程的SIGPIPE到SIG_IGN(忽略)的处置(全局) 。
执行以下管道时......
awk '{print $1}' testFile2.txt | sort -g | head -1
由于head
标志, ... sort
将从-1
命令打印第一行stdout后退出。当sort
命令尝试向其stdout写入更多行时,将引发SIGPIPE。
SIGPIPE的默认操作;例如,当管道在像bash这样的shell中执行时;是终止sort命令。
如前所述,python使用SIG_IGN(忽略)覆盖默认操作,因此我们最终会遇到这种奇怪的,有些莫名其妙的行为。
这一切都很好,但你可能想知道现在该做什么?它依赖于你正在使用的python版本......
对于Python 3.2及更高版本,您已经设置好了。 subprocess.Popen
in 3.2添加了restore_signals
参数,默认为True
,并且无需采取进一步操作即可有效解决问题。
对于以前的版本,您可以为preexec_fn
的{{1}}参数提供可调用,如... {/ p>
subprocess.Popen
我希望有所帮助!
编辑:应该注意到您的程序实际上正常运行,AFAICT,原样。您只是看到了直接在shell中执行脚本时通常看不到的其他错误消息(出于上述原因)。
另见: