gpt4 book ai didi

python - 使用子进程重定向 shell 输出

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:28:57 27 4
gpt4 key购买 nike

我有一个调用大量 shell 函数的 python 脚本。该脚本可以从终端交互式运行,在这种情况下我想立即显示输出,或者由 crontab 调用,在这种情况下我想通过电子邮件发送错误输出。

我写了一个调用 shell 函数的辅助函数:

import subprocess
import shlex
import sys

def shell(cmdline, interactive=True):
args = shlex.split(cmdline.encode("ascii"))
proc = subprocess.Popen(args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
val = proc.communicate()
if interactive is True:
if proc.returncode:
print "returncode " + str(proc.returncode)
print val[1]
sys.exit(1)
else:
print val[0]
else:
if proc.returncode:
print ""
# send email with val[0] + val[1]

if __name__ == "__main__":
# example of command that produces non-zero returncode
shell("ls -z")

我遇到的问题有两个。

1) 在交互模式下,当 shell 命令需要一段时间才能完成(例如几分钟)时,由于 communicate() 缓冲输出,在命令完全完成之前我看不到任何东西。有没有办法在输入时显示输出,并避免缓冲?我还需要一种检查返回码的方法,这就是我使用 communicate() 的原因。

2) 我调用的一些 shell 命令会产生大量输出(例如 2MB)。 documentation for communicate() 表示“如果数据量很大或不受限制,请勿使用此方法。”有谁知道“大”有多大?

最佳答案

1) 当您使用communicate 时,您会捕获子进程的输出,因此不会将任何内容发送到您的标准输出。您在子流程完成时看到输出的唯一原因是您自己打印了它。

由于您想在运行时看到它而不捕获它,或者捕获所有内容并仅在最后对它做一些事情,您可以通过离开 stdout 来更改它在交互模式下的工作方式和 stderrNone。这使得子进程使用与您的程序相同的流。您还必须将 communicate 的调用替换为 wait 的调用:

if interactive is True:
proc = subprocess.Popen(args)
proc.wait()
if proc.returncode:
print "returncode " + str(proc.returncode)
sys.exit(1)
else:
proc = subprocess.Popen(args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
val = proc.communicate()
if proc.returncode:
print ""
# send email with val[0] + val[1]

2) Too large 就是“太大而无法存储在内存中”,所以这一切都取决于很多因素。如果在您的情况下可以在内存中临时存储 2MB 的数据,则无需担心。

关于python - 使用子进程重定向 shell 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6560782/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com