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

Joh*_*ohn 253 python

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

var = os.system("cat /etc/services")
print var #Prints 0
Run Code Online (Sandbox Code Playgroud)

Chr*_*nch 378

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

os.popen('cat /etc/services').read()
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

  • 我不断遇到这个问题,每当我想知道 - 为什么有三行复杂的代码而不是一行明显的代码更好? (38认同)
  • @ChrisBunch为什么suprocess比`os.popen`更好的解决方案? (10认同)
  • 请注意,Walter的`subprocess.check_output`解决方案更接近你想要的Pythonic单线程,只要你不关心`stderr`. (6认同)
  • 你应该(几乎)永远不要使用`shell = True`.请参阅https://docs.python.org/3/library/subprocess.html#security-considerationshttps://docs.python.org/3/library/subprocess.html#security-considerations (6认同)
  • 你不仅(几乎)不会使用`shell = True`,但在这种情况下它也是不正确的.`shell = True`使_shell_成为子进程而不是`cat`,所以`out`和`err`是_shell_进程的stdout/stderr,而不是`cat`进程 (2认同)

Wal*_*ndt 166

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

import subprocess
output = subprocess.check_output("cat /etc/services", shell=True)
Run Code Online (Sandbox Code Playgroud)

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

  • @ghost21blade,你可能想研究一下:`output.decode("utf-8").split("\n")`或者你想用它做的任何事情。您必须首先将其转换为字符串(/sf/ask/42433401/)! (4认同)
  • 添加 `stderr=subprocess.STDOUT` 以捕获标准错误 (3认同)
  • 我将此方法与 ***systeminfo*** 命令一起使用。输出是像这样的***令人讨厌的***“b”\r\n主机名:DIMUTH-LAPTOP\r\n操作系统名称:Microsoft Windows 10 Pro\r\n操作系统版本:10.0.10240 N/A Build 10240 \r\n操作系统制造商:微软公司``` (3认同)
  • 注意,`check_output`是用python 2.7 https://docs.python.org/2.7/library/subprocess.html#subprocess.check_output添加的 (2认同)

ian*_*ury 45

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

import commands
status, output = commands.getstatusoutput("cat /etc/services")
Run Code Online (Sandbox Code Playgroud)

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

  • 引自[命令模块的文档](http://docs.python.org/2/library/commands.html#commands):*"自2.6版本后不推荐使用:在Python 3中删除了命令模块.使用而是子进程模块."*. (36认同)
  • @advocate查看子进程的check_output命令.它快速,简单,不会很快折旧! (5认同)
  • 确定它已经过时但有时你只想在几行代码中快速轻松地完成任务. (4认同)

Vas*_*kis 23

我知道这已经得到了解答,但我想通过使用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')
Run Code Online (Sandbox Code Playgroud)

  • 3 年后,这对我有用。我把它放在一个名为 `cmd.py` 的单独文件中,然后在我的主文件中我写了 `from cmd import cmdline` 并根据需要使用它。 (2认同)

Chi*_*nke 19

对于python 3.5+,建议您使用子进程模块中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"])
Run Code Online (Sandbox Code Playgroud)


lex*_*a-b 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
Run Code Online (Sandbox Code Playgroud)