Python:如何在运行 os.system 后获取标准输出?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18739239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 11:40:00  来源:igfitidea点击:

Python: How to get stdout after running os.system?

pythonpython-2.7stdoutstderros.system

提问by Eduard Florinescu

I want to get the stdoutin a variable after running the os.systemcall.

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

Lets take this line as an example:

让我们以这一行为例:

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

resultwill contain the error code (stderr0under Windows or 1under some linux for the above example).

result将包含错误代码(stderr0在 Windows 下或1在上述示例中的某些 linux 下)。

How can I get the stdoutfor the above command without using redirection in the executed command?

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

采纳答案by Martijn Pieters

If all you need is the stdoutoutput, then take a look at subprocess.check_output():

如果您只需要stdout输出,请查看subprocess.check_output()

import subprocess

batcmd="dir"
result = subprocess.check_output(batcmd, shell=True)

Because you were using os.system(), you'd have to set shell=Trueto get the same behaviour. You do want to heed the security concernsabout passing untrusted arguments to your shell.

因为您使用的是os.system(),所以您必须设置shell=True以获得相同的行为。您确实希望注意将不受信任的参数传递给 shell的安全问题

If you need to capture stderras well, simply add stderr=subprocess.STDOUTto the call:

如果您还需要捕获stderr,只需添加stderr=subprocess.STDOUT到调用中:

result = subprocess.check_output([batcmd], stderr=subprocess.STDOUT)

to redirect the error output to the default output stream.

将错误输出重定向到默认输出流。

If you know that the output is text, add text=Trueto decode the returned bytes value with the platform default encoding; use encoding="..."instead if that codec is not correct for the data you receive.

如果您知道输出是文本,则添加text=True以使用平台默认编码对返回的字节值进行解码;使用encoding="..."而不是如果该编解码器是不适合你接收到的数据是正确的。

回答by LateNiteOwl

I would like to expand on the Windows solution. Using IDLE with Python 2.7.5, When I run this code from file Expts.py:

我想扩展 Windows 解决方案。在 Python 2.7.5 中使用 IDLE,当我从文件 Expts.py 运行此代码时:

import subprocess
r = subprocess.check_output('cmd.exe dir',shell=False) 
print r

...in the Python Shell, I ONLY get the output corresponding to "cmd.exe"; the "dir" part is ignored. HOWEVER, when I add a switch such as /K or /C ...

...在Python Shell中,我只得到“cmd.exe”对应的输出;“dir”部分被忽略。但是,当我添加诸如 /K 或 /C 之类的开关时...

import subprocess
r = subprocess.check_output('cmd.exe /K dir',shell=False) 
print r

...then in the Python Shell, I get all that I expect including the directory listing. Woohoo !

...然后在 Python Shell 中,我得到了我期望的所有内容,包括目录列表。呜呼!

Now, if I try any of those same things in DOS Python command window, without the switch, or with the /K switch, it appears to make the window hang because it is running a subprocess cmd.exe and it awaiting further input - type 'exit' then hit [enter] to release. But with the /K switch it works perfectly and returns you to the python prompt. Allrightee then.

现在,如果我在不使用开关或使用 /K 开关的 DOS Python 命令窗口中尝试任何相同的操作,它似乎会使窗口挂起,因为它正在运行子进程 cmd.exe 并等待进一步输入 - 键入'exit' 然后按 [enter] 释放。但是使用 /K 开关,它可以完美运行并返回到 python 提示符。那么好吧。

Went a step further...I thought this was cool...When I instead do this in Expts.py:

更进一步......我认为这很酷......当我在Expts.py中这样做时:

import subprocess
r = subprocess.call("cmd.exe dir",shell=False) 
print r

...a new DOS window pops open and remains there displaying only the results of "cmd.exe" not of "dir". When I add the /C switch, the DOS window opens and closes very fast before I can see anything (as expected, because /C terminates when done). When I instead add the /K switch, the DOS window pops open and remain, AND I get all the output I expect including the directory listing.

...一个新的 DOS 窗口弹出并停留在那里,只显示“cmd.exe”而不是“dir”的结果。当我添加 /C 开关时,DOS 窗口在我看到任何东西之前打开和关闭的速度非常快(正如预期的那样,因为 /C 在完成后终止)。当我改为添加 /K 开关时,DOS 窗口会弹出并保持打开状态,并且我得到了我期望的所有输出,包括目录列表。

If I try the same thing (subprocess.call instead of subprocess.check_output) from a DOS Python command window; all output is within the same window, there are no popup windows. Without the switch, again the "dir" part is ignored, AND the prompt changes from the python prompt to the DOS prompt (since a cmd.exe subprocess is running in python; again type 'exit' and you will revert to the python prompt). Adding the /K switch prints out the directory listing and changes the prompt from python to DOS since /K does not terminate the subprocess. Changing the switch to /C gives us all the output expected AND returns to the python prompt since the subprocess terminates in accordance with /C.

如果我从 DOS Python 命令窗口尝试同样的事情(subprocess.call 而不是 subprocess.check_output);所有输出都在同一个窗口中,没有弹出窗口。如果没有开关,“dir”部分再次被忽略,并且提示从 python 提示符变为 DOS 提示符(因为 cmd.exe 子进程正在 python 中运行;再次键入“退出”,您将恢复到 python 提示符)。添加 /K 开关会打印出目录列表并将提示从 python 更改为 DOS,因为 /K 不会终止子进程。将开关更改为 /C 为我们提供了所有预期的输出并返回到 python 提示符,因为子进程根据 /C 终止。

Sorry for the long-winded response, but I am frustrated on this board with the many terse 'answers' which at best don't work (seems because they are not tested - like Eduard F's response above mine which is missing the switch) or worse, are so terse that they don't help much at all (e.g., 'try subprocess instead of os.system' ... yeah, OK, now what ??). In contrast, I have provided solutions which I tested, and showed how there are subtle differences between them. Took a lot of time but... Hope this helps.

对于冗长的回复,我很抱歉,但我对这个板上的许多简洁的“答案”感到沮丧,这些“答案”充其量不起作用(似乎是因为它们没有经过测试 - 就像我上面的 Eduard F 的响应缺少开关)或更糟糕的是,它们是如此简洁以至于它们根本没有多大帮助(例如,'尝试子进程而不是 os.system'......是的,好的,现在呢??)。相比之下,我提供了经过测试的解决方案,并展示了它们之间的细微差别。花了很多时间但是...希望这会有所帮助。

回答by Patrick

These answers didn't work for me. I had to use the following:

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

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

Or as a function (using shell=True was required for me on Python 2.6.7 and check_output was not added until 2.7, making it unusable here):

或者作为一个函数(在 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()

回答by buxizhizhoum

commandsalso works.

commands也有效。

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

It works on linux, python 2.7.

它适用于 linux,python 2.7。

回答by Edhowler

I had to use os.system, since subprocess was giving me a memory error for larger tasks. Reference for this problem here. So, in order to get the output of the os.system command I used this workaround:

我不得不使用 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)

回答by Syed Wasim

import subprocess
string="echo Hello world"
result=subprocess.getoutput(string)
print("result::: ",result)