125

我想stdout在运行后获取变量os.system调用后获取变量。

让我们以这一行为例:

batcmd="dir"
result = os.system(batcmd)

result将包含错误代码(stderr 0在 Windows 或1某些 linux 下)。

如何stdout在执行的命令中不使用重定向来获取上述命令?

4

6 回答 6

154

如果您只需要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="..."如果该编解码器对于您收到的数据不正确,请改用。

于 2013-09-11T11:24:23.580 回答
25

这些答案对我不起作用。我不得不使用以下内容:

import subprocess
p = subprocess.Popen(["pwd"], stdout=subprocess.PIPE)
out = p.stdout.read()
print out

或者作为一个函数(在 Python 2.6.7 上我需要使用 shell=True 并且 check_output 直到 2.7 才添加,使其在此处无法使用):

def system_call(command):
    p = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True)
    return p.stdout.read()
于 2014-10-13T15:38:42.907 回答
14
import subprocess
string="echo Hello world"
result=subprocess.getoutput(string)
print("result::: ",result)
于 2019-09-12T16:27:04.433 回答
9

我不得不使用 os.system,因为对于较大的任务,子进程给了我一个内存错误。这个问题的参考在这里。因此,为了获得 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)
于 2019-01-08T20:27:36.320 回答
8

我想扩展 Windows 解决方案。在 Python 2.7.5 中使用 IDLE,当我从文件 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 在我上面的回应缺少开关)或更糟糕的是,它们是如此简洁以至于它们根本没有多大帮助(例如,'尝试使用子进程而不是 os.system'......是的,好的,现在是什么??)。相比之下,我提供了我测试过的解决方案,并展示了它们之间的细微差别。花了很多时间但是......希望这会有所帮助。

于 2014-07-12T23:53:54.320 回答
5

commands也有效。

import commands
batcmd = "dir"
result = commands.getoutput(batcmd)
print result

它适用于linux,python 2.7。

于 2017-07-28T03:45:09.247 回答