Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 写入错误:管道断开_Python_Linux_Unix_Scripting - Fatal编程技术网

Python 写入错误:管道断开

Python 写入错误:管道断开,python,linux,unix,scripting,Python,Linux,Unix,Scripting,我必须在大约300个目录上运行一个工具。每次跑步大约需要1分钟到30分钟,甚至更多。因此,我编写了一个python脚本,其中包含一个循环,可以在所有目录上一个接一个地运行该工具 我的python脚本的代码类似于: for directory in directories: os.popen('runtool_exec ' + directory) devnull = open(os.devnull, 'w') for directory in directories: subpro

我必须在大约300个目录上运行一个工具。每次跑步大约需要1分钟到30分钟,甚至更多。因此,我编写了一个python脚本,其中包含一个循环,可以在所有目录上一个接一个地运行该工具

我的python脚本的代码类似于:

for directory in directories:
  os.popen('runtool_exec ' + directory)
devnull = open(os.devnull, 'w')
for directory in directories:
    subprocess.Popen(['runtool_exec', directory], stdout=devnull)
但是,当我运行python脚本时,会反复收到以下错误消息:

..
tail: write error: Broken pipe
date: write error: Broken pipe
..
我所做的就是使用ssh登录远程服务器,在那里保存工具、python脚本和主题目录。当我使用以下命令从命令提示符下单独运行该工具时:

runtool_exec directory
它很好用。只有在使用python脚本运行时,才会出现“断管”错误。
有什么想法,解决方法吗?

您看到的错误是因为您正在使用
os.popen()
运行命令,这意味着管道已打开并连接到命令的
stdout
。每当命令(或它在不重定向stdout的情况下执行的任何命令)想要写入stdout时,它都会尝试写入管道。但是,由于没有将
os.popen()
的结果分配到任何地方,因此不会保留管道,因此它会被Python清理并关闭。因此,尝试写入它的进程会遇到一个断开的管道,并产生您看到的错误。(
os.popen()

os.popen()
调用中的另一个问题是,您没有检查
目录
是否包含shell的任何特殊字符。例如,如果目录中包含引号或*,则可能会发生奇怪的事情。像那样使用
os.popen()
是非常糟糕的

您应该改用
subprocess.Popen()
,并明确告诉它您想对流程的输出(stdout和stderr)执行什么操作。您可以传递
subprocess.Popen()
一个参数列表(包括要启动的内容),而不是单个字符串,而且它完全避免了shell——不需要检查字符串的完整性。如果您真的想忽略输出,可以使用以下方法:

for directory in directories:
  os.popen('runtool_exec ' + directory)
devnull = open(os.devnull, 'w')
for directory in directories:
    subprocess.Popen(['runtool_exec', directory], stdout=devnull)

尽管我强烈建议至少对subprocess.Popen的结果进行一些基本检查,以查看该进程是否过早执行或出现错误代码。

如果这对其他任何人都有帮助,同样的问题可能是在shell命令中使用管道(|)的结果。请参见此处了解解决方案

非常感谢您的回答。这很有效。但如何确定哪个进程成功完成,哪个进程出错?以及如何确定哪些进程仍在运行?有没有办法等待子流程完成?我目前正在尝试:log=open(logFile'a');process=subprocess.Popen(args,stdout=log)process.wait()如果process.returncode>=0:print'done!'否则:打印错误!“进程终止得很糟糕”,但我发现它不会等待进程完成,返回代码总是99。请帮助。如果它没有等待流程完成,那么返回代码将是
None
,而不是99。您描述的内容表明,您启动的命令不会等待它启动的任何进程,并且您启动的命令返回99。问题在于您启动的进程,而不是使用
subprocess.Popen()
。(另外,如果您总是想等待进程退出,那么使用
subprocess.call()
会更容易一些。)