2010-04-25 143 views
4

我必须在大约300个目录上运行一个工具。每次运行大约需要1分钟到30分钟甚至更多。于是,我编写了一个python脚本,它有一个循环以便在所有目录上依次运行该工具。写错误:损坏的管道

我的Python脚本有代码是这样的:

for directory in directories: 
    os.popen('runtool_exec ' + directory) 

但是当我运行python脚本,我得到了以下错误消息多次:

.. 
tail: write error: Broken pipe 
date: write error: Broken pipe 
.. 

我所要做的就是在远程服务器上登录使用ssh保存工具,python脚本和主题目录。当我从命令提示符使用命令单独运行该工具时:

runtool_exec directory 

它工作正常。只有当我使用python脚本运行时,“断开的管道”错误才会到来。 任何想法,解决方法?

回答

9

你看到的错误是因为您使用os.popen()运行命令,这意味着管道被打开并连接到命令的stdout。每当命令(或其执行任何不执行重定向stdout)想要写入stdout时,它都会尝试写入管道。但是你并没有保留管道,因为你没有在任何地方分配os.popen()的结果,所以它被Python清理并关闭。所以试图写入它的进程遇到一个坏的管道,并产生你看到的错误。 (os.popen()重定向stderr到管道,所以你仍然可以看到这些错误。)

os.popen()调用另一个问题是,你不检查,以确保directory不包含特殊字符,任何你贝壳。如果目录包含引号或例如*,可能会发生奇怪的事情。使用os.popen()这样很不好。

您应该使用subprocess.Popen()代替,并明确告诉它要与过程的输出做什么(标准输出和标准错误。)你传递subprocess.Popen()参数(包括要启动的东西)的列表,而不是一个单一的字符串,它完全避免了shell - 无需理智地检查你的字符串。如果你真的想忽略的输出,你会喜欢的东西做到这一点:

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

虽然我会强烈建议至少做对subprocess.Popen的结果,一些基本的检查,看是否该过程没有过早执行或使用错误代码执行。

+0

非常感谢您的答案。这工作。但是,我怎样才能确定哪个进程成功完成以及哪个出错? – Fahim 2010-04-25 23:32:23

+0

以及如何确定哪些进程仍在运行?有什么方法可以等待子流程完成吗? – Fahim 2010-04-25 23:49:59

+0

我正在尝试这个: log = open(logFile,'a'); 过程= subprocess.Popen(参数,标准输出=日志) process.wait() 如果过程。返回码> = 0:\t \t \t \t \t \t \t \t \t打印 '完成了!' \t else: \t print'Error!进程终止严重' 但我看到它不会等待进程完成,并且返回代码始终为99. 请大家帮忙。 – Fahim 2010-04-26 01:28:11

相关问题