我必须在大约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脚本运行时才会出现“断管”错误。 有什么主意,解决办法吗?
您看到的错误是因为您正在使用
os.popen()
运行该命令,这意味着管道已打开并连接到该命令的stdout
。每当命令(或者它执行的任何东西没有重定向stdout
)想要写入stdout
,它就会尝试写入管道。但是您不需要保留管道,因为您不在任何地方分配os.popen()
的结果,所以它被Python清理并关闭。因此,试图向其写入的进程遇到一个断管,并产生您看到的错误。(os.popen()
没有将stderr
重定向到管道,因此仍然可以看到错误。)在您的
os.popen()
调用中的另一个问题是,您没有检查以确保directory
不包含任何特定于shell的字符。例如,如果目录包含引号或*,可能会发生奇怪的事情。像这样使用os.popen()
相当糟糕。您应该改用
subprocess.Popen()
,并显式地告诉它您想对进程的输出(stdout和stderr)做些什么。您传递subprocess.Popen()
一个参数列表(包括您想启动的东西)而不是一个字符串,它完全避免了shell——不需要检查字符串。如果您真的想忽略输出,可以使用以下方法:尽管我强烈建议至少对subprocess.Popen的结果进行一些初步检查,看看该进程是否过早执行或错误代码。
如果这对其他任何人都有帮助,那么在shell命令中使用管道(|)也可能导致同样的问题。参见此处了解解决方案https://stackoverflow.com/a/4106633/1904913
相关问题 更多 >
编程相关推荐