Fah*_*him 4 python unix linux scripting
我必须在大约300个目录上运行一个工具.每次运行大约需要1分钟到30分钟甚至更长时间.所以,我写了一个python脚本,有一个循环,一个接一个地在所有目录上运行该工具.
我的python脚本有类似的代码:
for directory in directories:
os.popen('runtool_exec ' + directory)
Run Code Online (Sandbox Code Playgroud)
但是当我运行python脚本时,我反复收到以下错误消息:
..
tail: write error: Broken pipe
date: write error: Broken pipe
..
Run Code Online (Sandbox Code Playgroud)
我所做的就是使用ssh登录远程服务器,其中保存工具,python脚本和主题目录.当我使用以下命令从命令提示符单独运行该工具时:
runtool_exec directory
Run Code Online (Sandbox Code Playgroud)
它工作正常.只有当我使用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一共 - 不需要理智 - 检查你的字符串.如果你真的想忽略输出,你可以这样做:
devnull = open(os.devnull, 'w')
for directory in directories:
subprocess.Popen(['runtool_exec', directory], stdout=devnull)
Run Code Online (Sandbox Code Playgroud)
虽然我强烈建议至少对subprocess.Popen的结果进行一些初步的检查,以查看进程是否过早执行或者是否有错误代码.