关于python:将os.system的输出分配给变量并防止它显示在屏幕上

Assign output of os.system to a variable and prevent it from being displayed on the screen

我想将使用os.system运行的命令的输出分配给变量,并防止它输出到屏幕。 但是,在下面的代码中,输出被发送到屏幕并且为var打印的值为0,我猜这意味着命令是否成功运行。 有没有办法将命令输出分配给变量并阻止它显示在屏幕上?

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


从我很久以前问过的"Python中的Bash Backticks的等价",你可能想要使用的是popen

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

从Python 3.6的文档中,

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

这是subprocess的相应代码:

1
2
3
4
5
import subprocess

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


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

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

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


命令模块是一种相当高级的方法:

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

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


我知道这已经得到了解答,但我想通过使用from x import x和函数分享一种可能更好看的方式来调用Popen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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')


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

1
2
3
4
5
6
7
8
9
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"])

我使用os.system临时文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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


Python 2.6和3特别指出要避免将PIPE用于stdout和stderr。

正确的方法是

1
2
3
4
5
6
7
8
9
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