管道弹出标准错误和标准输出
Posted
技术标签:
【中文标题】管道弹出标准错误和标准输出【英文标题】:Piping popen stderr and stdout 【发布时间】:2012-05-21 10:02:22 【问题描述】:我想通过 python 从目录调用脚本(它们是可执行的 shell 脚本)。
到目前为止一切顺利:
for script in sorted(os.listdir(initdir), reverse=reverse):
if script.endswith('.*~') or script == 'README':
continue
if os.access(script, os.X_OK):
try:
execute = os.path.abspath(script)
sp.Popen((execute, 'stop' if reverse else 'start'),
stdin=None, stderr=sp.PIPE,
stdout=sp.stderr, shell=True).communicate()
except:
raise
现在我想要的是:假设我有一个带有启动功能的 bash 脚本。我从中调用
回显“某事”
现在我想在 sys.stdout 和退出代码上看到那个回声。我相信您可以使用 .communicate() 来执行此操作,但我的并没有像我想象的那样工作。
我做错了什么?
非常感谢任何帮助
【问题讨论】:
【参考方案1】:授予http://docs.python.org/library/subprocess.html。
communicate() 返回一个元组 (stdoutdata, stderrdata)。
子进程完成后,您可以从 Popen 实例中获取返回码:
Popen.returncode:子返回码,由 poll() 和 wait() 设置(间接通过communicate())。
同样,您也可以这样实现目标:
sp = subprocess.Popen([executable, arg1, arg2], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = sp.communicate()
if out:
print "standard output of subprocess:"
print out
if err:
print "standard error of subprocess:"
print err
print "returncode of subprocess:"
print sp.returncode
顺便说一句,我会改变测试
if script.endswith('.*~') or script == 'README':
continue
变成正面的:
if not filename.endswith(".sh"):
continue
明确说明您想要执行的内容比明确说明您不想要执行的内容更好。
此外,您应该以更通用的方式命名变量,因此 script
首先应该是 filename
。由于listdir
还列出了目录,您可以明确检查这些目录。只要您不处理特定异常,您当前的 try/except
块就不合适。而不是abspath
,您应该只连接initdir
和filename
,这是os.listdir()
上下文中经常应用的概念。出于安全原因,仅当您完全确定需要它时,才在Popen
对象的构造函数中使用shell=True
。让我提出以下建议:
for filename in sorted(os.listdir(initdir), reverse=reverse):
if os.path.isdir(filename) or not filename.endswith(".sh"):
continue
if os.access(script, os.X_OK):
exepath = os.path.join(initdir, filename)
sp = subprocess.Popen(
(exepath, 'stop' if reverse else 'start'),
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
out, err = sp.communicate()
print out, err, sp.returncode
【讨论】:
是的,我有特定的例外情况,我只是没有输入它们,因为您与问题无关。但是你对变量名是正确的,我总是在为正确的名字而苦恼,所以再次感谢以上是关于管道弹出标准错误和标准输出的主要内容,如果未能解决你的问题,请参考以下文章