将os.system的输出分配给变量,并防止其在屏幕上显示

问题:将os.system的输出分配给变量,并防止其在屏幕上显示

我想将我使用的命令的输出分配给os.system变量,并防止将其输出到屏幕。但是,在下面的代码中,输出将发送到屏幕,并且打印的var值为0,我猜这表明命令是否成功运行。有什么方法可以将命令输出分配给变量,也可以阻止它在屏幕上显示?

var = os.system("cat /etc/services")
print var #Prints 0

I want to assign the output of a command I run using os.system to a variable and prevent it from being output to the screen. But, in the below code ,the output is sent to the screen and the value printed for var is 0, which I guess signifies whether the command ran successfully or not. Is there any way to assign the command output to the variable and also stop it from being displayed on the screen?

var = os.system("cat /etc/services")
print var #Prints 0

回答 0

从我很久以前问过的“ Python中的Bash反引号等效 ”中,您可能想使用的是popen

os.popen('cat /etc/services').read()

Python 3.6文档中

这是使用subprocess.Popen实现的;有关更强大的方法来管理子流程和与子流程进行通信,请参见该类的文档。


这是对应的代码subprocess

import subprocess

proc = subprocess.Popen(["cat", "/etc/services"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out

From “Equivalent of Bash Backticks in Python“, which I asked a long time ago, what you may want to use is popen:

os.popen('cat /etc/services').read()

From the docs for Python 3.6,

This is implemented using subprocess.Popen; see that class’s documentation for more powerful ways to manage and communicate with subprocesses.


Here’s the corresponding code for subprocess:

import subprocess

proc = subprocess.Popen(["cat", "/etc/services"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out

回答 1

您可能还需要查看该subprocess模块,该模块是为替换整个Python popen类型调用系列而构建的。

import subprocess
output = subprocess.check_output("cat /etc/services", shell=True)

它的优点是在调用命令,连接标准输入/输出/错误流等方面具有很大的灵活性。

You might also want to look at the subprocess module, which was built to replace the whole family of Python popen-type calls.

import subprocess
output = subprocess.check_output("cat /etc/services", shell=True)

The advantage it has is that there is a ton of flexibility with how you invoke commands, where the standard in/out/error streams are connected, etc.


回答 2

命令模块是执行此操作的合理的高级方法:

import commands
status, output = commands.getstatusoutput("cat /etc/services")

status为0,输出为/ etc / services的内容。

The commands module is a reasonably high-level way to do this:

import commands
status, output = commands.getstatusoutput("cat /etc/services")

status is 0, output is the contents of /etc/services.


回答 3

对于python 3.5+,建议您使用subprocess模块​​中run函数。这将返回一个CompletedProcess对象,您可以从该对象轻松获取输出以及返回代码。由于您只对输出感兴趣,因此可以编写这样的实用程序包装。

from subprocess import PIPE, run

def out(command):
    result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True)
    return result.stdout

my_output = out("echo hello world")
# Or
my_output = out(["echo", "hello world"])

For python 3.5+ it is recommended that you use the run function from the subprocess module. This returns a CompletedProcess object, from which you can easily obtain the output as well as return code. Since you are only interested in the output, you can write a utility wrapper like this.

from subprocess import PIPE, run

def out(command):
    result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True)
    return result.stdout

my_output = out("echo hello world")
# Or
my_output = out(["echo", "hello world"])

回答 4

我知道已经解决了这个问题,但是我想分享一种通过使用from x import x和函数来调用Popen的可能更好的方法:

from subprocess import PIPE, Popen


def cmdline(command):
    process = Popen(
        args=command,
        stdout=PIPE,
        shell=True
    )
    return process.communicate()[0]

print cmdline("cat /etc/services")
print cmdline('ls')
print cmdline('rpm -qa | grep "php"')
print cmdline('nslookup google.com')

I know this has already been answered, but I wanted to share a potentially better looking way to call Popen via the use of from x import x and functions:

from subprocess import PIPE, Popen


def cmdline(command):
    process = Popen(
        args=command,
        stdout=PIPE,
        shell=True
    )
    return process.communicate()[0]

print cmdline("cat /etc/services")
print cmdline('ls')
print cmdline('rpm -qa | grep "php"')
print cmdline('nslookup google.com')

回答 5

我用os.system临时文件来做:

import tempfile,os
def readcmd(cmd):
    ftmp = tempfile.NamedTemporaryFile(suffix='.out', prefix='tmp', delete=False)
    fpath = ftmp.name
    if os.name=="nt":
        fpath = fpath.replace("/","\\") # forwin
    ftmp.close()
    os.system(cmd + " > " + fpath)
    data = ""
    with open(fpath, 'r') as file:
        data = file.read()
        file.close()
    os.remove(fpath)
    return data

i do it with os.system temp file:

import tempfile,os
def readcmd(cmd):
    ftmp = tempfile.NamedTemporaryFile(suffix='.out', prefix='tmp', delete=False)
    fpath = ftmp.name
    if os.name=="nt":
        fpath = fpath.replace("/","\\") # forwin
    ftmp.close()
    os.system(cmd + " > " + fpath)
    data = ""
    with open(fpath, 'r') as file:
        data = file.read()
        file.close()
    os.remove(fpath)
    return data

回答 6

Python 2.6和3明确表示要避免将PIPE用于stdout和stderr。

正确的方法是

import subprocess

# must create a file object to store the output. Here we are getting
# the ssid we are connected to
outfile = open('/tmp/ssid', 'w');
status = subprocess.Popen(["iwgetid"], bufsize=0, stdout=outfile)
outfile.close()

# now operate on the file

Python 2.6 and 3 specifically say to avoid using PIPE for stdout and stderr.

The correct way is

import subprocess

# must create a file object to store the output. Here we are getting
# the ssid we are connected to
outfile = open('/tmp/ssid', 'w');
status = subprocess.Popen(["iwgetid"], bufsize=0, stdout=outfile)
outfile.close()

# now operate on the file