Python:运行 os.system 后如何获取 stdout?[重复]
- 2025-02-21 08:48:00
- admin 原创
- 33
问题描述:
我想在运行调用后获取stdout
变量中的内容os.system
。
让我们以此行为例:
batcmd="dir"
result = os.system(batcmd)
result
将包含错误代码(对于上述示例,stderr
0
在 Windows 下或某些 Linux 下)。1
如何stdout
在不在执行的命令中使用重定向的情况下获取上述命令?
解决方案 1:
如果您需要的只是stdout
输出,请查看subprocess.check_output()
:
import subprocess
batcmd="dir"
result = subprocess.check_output(batcmd, shell=True)
因为您使用的是os.system()
,所以您必须设置shell=True
才能获得相同的行为。您确实需要注意将不受信任的参数传递给 shell 的安全问题。
stderr
如果您也需要捕获,只需添加stderr=subprocess.STDOUT
到调用中:
result = subprocess.check_output([batcmd], stderr=subprocess.STDOUT)
将错误输出重定向到默认输出流。
如果您知道输出是文本,请添加text=True
使用平台默认编码解码返回的字节值;encoding="..."
如果该编解码器对于您收到的数据不正确,则使用。
解决方案 2:
import subprocess
string="echo Hello world"
result=subprocess.getoutput(string)
print("result::: ",result)
解决方案 3:
这些答案对我不起作用。 我必须使用以下内容:
import subprocess
p = subprocess.Popen(["pwd"], stdout=subprocess.PIPE)
out = p.stdout.read()
print out
或者作为一个函数(在 Python 2.6.7 上我需要使用 shell=True 并且直到 2.7 才添加 check_output,因此在这里无法使用):
def system_call(command):
p = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True)
return p.stdout.read()
解决方案 4:
我不得不使用 os.system,因为 subprocess 在执行较大任务时会给出内存错误。此问题的参考资料在这里。因此,为了获取 os.system 命令的输出,我使用了以下解决方法:
import os
batcmd = 'dir'
result_code = os.system(batcmd + ' > output.txt')
if os.path.exists('output.txt'):
fp = open('output.txt', "r")
output = fp.read()
fp.close()
os.remove('output.txt')
print(output)
解决方案 5:
我想扩展 Windows 解决方案。使用 IDLE 和 Python 2.7.5,当我从文件 Expts.py 运行此代码时:
import subprocess
r = subprocess.check_output('cmd.exe dir',shell=False)
print r
...在 Python Shell 中,我仅获得与“cmd.exe”对应的输出;“dir”部分被忽略。但是,当我添加诸如 /K 或 /C 之类的开关时...
import subprocess
r = subprocess.check_output('cmd.exe /K dir',shell=False)
print r
...然后在 Python Shell 中,我得到了我期望的所有内容,包括目录列表。哇哦!
现在,如果我在 DOS Python 命令窗口中尝试上述任何操作,不使用开关或使用 /K 开关,它似乎会使窗口挂起,因为它正在运行子进程 cmd.exe 并等待进一步输入 - 键入“exit”,然后按 [enter] 释放。但使用 /K 开关,它可以完美运行并返回到 python 提示符。好吧。
更进一步...我认为这很酷...当我在 Expts.py 中执行此操作时:
import subprocess
r = subprocess.call("cmd.exe dir",shell=False)
print r
...一个新的 DOS 窗口弹出并停留在那里,只显示“cmd.exe”的结果,而不是“dir”的结果。当我添加 /C 开关时,DOS 窗口打开并关闭得非常快,我还没来得及看到任何东西(正如预期的那样,因为 /C 在完成后终止)。当我添加 /K 开关时,DOS 窗口弹出并停留在那里,而且我得到了我期望的所有输出,包括目录列表。
如果我从 DOS Python 命令窗口尝试执行相同的操作(subprocess.call 而不是 subprocess.check_output);所有输出都在同一个窗口中,没有弹出窗口。如果没有开关,则再次忽略“dir”部分,并且提示符从 python 提示符更改为 DOS 提示符(因为 cmd.exe 子进程正在 python 中运行;再次键入“exit”,您将恢复到 python 提示符)。添加 /K 开关会打印出目录列表,并将提示符从 python 更改为 DOS,因为 /K 不会终止子进程。将开关更改为 /C 会为我们提供所有预期的输出,并且返回到 python 提示符,因为子进程按照 /C 终止。
抱歉回复得这么冗长,但我对这个论坛上许多简洁的“答案”感到失望,这些答案充其量是不起作用的(似乎是因为它们没有经过测试 - 就像 Eduard F 在我上面的回复中缺少开关)或者更糟的是,它们太简洁了,根本没有多大帮助(例如,“尝试使用 subprocess 而不是 os.system”...是的,好的,现在怎么办??)。相比之下,我提供了经过测试的解决方案,并展示了它们之间的细微差别。花了很多时间,但...希望这能有所帮助。
解决方案 6:
commands
也有效。
import commands
batcmd = "dir"
result = commands.getoutput(batcmd)
print result
它适用于 Linux、Python 2.7。