写入错误:pip断开

2024-06-17 18:00:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我必须在大约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脚本运行时才会出现“断管”错误。 有什么主意,解决办法吗?


Tags: 工具代码in目录脚本for错误error
2条回答

您看到的错误是因为您正在使用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)

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

如果这对其他任何人都有帮助,那么在shell命令中使用管道(|)也可能导致同样的问题。参见此处了解解决方案https://stackoverflow.com/a/4106633/1904913

相关问题 更多 >