Mat*_*Mat 4 python bash shell subprocess broken-pipe
我正在尝试从基于 GUI 的软件启动几个 bash 例程。我面临的问题是管道问题。这里是测试 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
Run Code Online (Sandbox Code Playgroud)
这里是创建错误的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])
Run Code Online (Sandbox Code Playgroud)
从运行 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
Run Code Online (Sandbox Code Playgroud)
好的,所以这有点晦涩,但碰巧我在研究python-tutor邮件列表上的一个问题时遇到了类似的问题。
通过 subprocess 模块(在 python 中)与直接通过 bash 运行脚本时,您看到不同行为的原因是,python 将所有子进程(全局)的 SIGPIPE 配置覆盖为 SIG_IGN(忽略)。
当执行以下管道时...
awk '{print $1}' testFile2.txt | sort -g | head -1
Run Code Online (Sandbox Code Playgroud)
...由于标志的原因,head它将在从sort命令打印第一行 stdout 后退出-1。当sort命令尝试将更多行写入其标准输出时,会引发 SIGPIPE。
SIGPIPE 的默认操作;例如,当管道在像 bash 这样的 shell 中执行时;是终止排序命令。
如前所述,python 使用 SIG_IGN(忽略)覆盖了默认操作,因此我们最终会出现这种奇怪且有些莫名其妙的行为。
这一切都很好,但您可能想知道现在该怎么办?这取决于您使用的python版本......
对于 Python 3.2 及更高版本,您已经设置好了。subprocess.Popen3.2中增加了restore_signals参数,默认为True,有效解决问题,无需进一步操作。
对于以前的版本,您可以为 的preexec_fn参数提供一个可调用对象subprocess.Popen,如...
import signal
def default_sigpipe():
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
# ...
with open('log.txt','w') as outfile:
CLEAN=subprocess.Popen("./bashScriptTest.sh",
stdout=outfile, stderr=outfile
preexec_fn=default_sigpipe)
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助!
编辑:应该注意的是,您的程序实际上运行正常,AFAICT,按原样。您只会看到在 shell 中直接执行脚本时通常不会看到的其他错误消息(出于上述原因)。
也可以看看:
| 归档时间: |
|
| 查看次数: |
3592 次 |
| 最近记录: |