管道Popen标准错误和标准输出

30

我想通过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

现在我想要的是:假设我有一个具有start函数的bash脚本,我从中调用

echo "Something"

现在我想在sys.stdout上看到这个echo输出和退出码。我相信可以使用.communicate()实现,但我的方法不起作用。

我做错了什么?

非常感谢任何帮助。

1个回答

74

请参阅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块就不正确。您应该使用os.listdir()上下文中经常应用的概念,而不是abspath,只需连接initdirfilename即可。出于安全原因,仅当您绝对确定需要时,才在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

是的,我有特定的异常,只是没有打出来,因为它们与问题无关。但你对于变量名是正确的,我总是在命名方面有困难,所以再次感谢。 - wagner-felix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接