Python中不输出结果的os.system函数

39

我正在运行以下代码:

os.system("/etc/init.d/apache2 restart")

它重新启动了Web服务器,正如应该的那样,并且像在终端中直接运行命令时一样,输出如下:

* Restarting web server apache2 ... waiting [ OK ]

然而,我不希望它实际上在我的应用程序中输出。 我该如何禁用它? 谢谢!


5
os.system("/etc/init.d/apache2 restart >/dev/null")会将输出丢弃。如Noufal所说,更推荐使用subprocess。但如果你想快速修改现有的代码,重定向到/dev/null可能是一种吸引人的选择。 - Kirk Strauser
1
@kirk:为什么是评论而不是答案? - mb14
1
@mb14:我认为这种方法并不像使用子进程那样“正确”。我认为它更像是一个旁注,就像“虽然我并不完全建议你这样做,但这是另一个想法。” - Kirk Strauser
如何在Python 2.7中隐藏子进程的输出 - jfs
这对我很有用,因为我正在寻找适用于Python 2和3的解决方案。 - ChathuraG
您还可以查看是否有安静或无声的命令行选项。但是,这并不保证程序不会输出stderr。 - Sushila Jyothi Lévêque
7个回答

64

一定要避免使用os.system(),而是使用subprocess代替:

with open(os.devnull, 'wb') as devnull:
    subprocess.check_call(['/etc/init.d/apache2', 'restart'], stdout=devnull, stderr=subprocess.STDOUT)

这是subprocess相当于/etc/init.d/apache2 restart &> /dev/null的命令。

在Python 3.3+中有subprocess.DEVNULL

#!/usr/bin/env python3
from subprocess import DEVNULL, STDOUT, check_call

check_call(['/etc/init.d/apache2', 'restart'], stdout=DEVNULL, stderr=STDOUT)

3
+1пјҢжҸҗдҫӣдёҖдёӘдҪҝз”Ёsubprocessи§ЈеҶіOPй—®йўҳзҡ„е®һйҷ…зӨәдҫӢгҖӮ :) - Noufal Ibrahim

38

根据您的操作系统(这也是为什么如Noufal所说,您应该使用subprocess)您可以尝试类似于以下内容:

 os.system("/etc/init.d/apache restart > /dev/null")
或者(为了静音也可以隐藏错误)
os.system("/etc/init.d/apache restart > /dev/null 2>&1")

25
您应该使用subprocess模块,通过它可以灵活地控制stdoutstderr。而os.system已经被弃用。 subprocess模块允许您创建表示正在运行的外部进程的对象。您可以从其stdout/stderr读取内容,写入stdin,发送信号,终止等。该模块中的主要对象是Popen。还有一堆其他方便的方法,如call等。 文档非常全面,并包括一个替换旧函数(包括os.system)的部分

4
+10 对于一个不完整的答案!这表明投票和质量不是密不可分的 :-)。 Noufal,你可以提到不同之处。 - user225312
1
popen 但你应该花些时间仔细阅读文档。我想你只是草草地浏览了一遍。它们非常清晰明了。 - Noufal Ibrahim
2
你有明确标记它为“已弃用”的源吗,而不是“不推荐使用”?Guido曾表示反对将其删除。我并不反对你的答案 - subprocess更好! - 只是澄清一个观点。 - Kirk Strauser
1
Guido通常不赞成更改标准库。os.system的文档表明最好使用subprocess - Noufal Ibrahim
A:我认为它已经相当完整了。需要的只是指向“正确”方法的指针。虽然我对得到的赞数感到惊讶。我已经更新了一些信息。 - Noufal Ibrahim
显示剩余2条评论

1

这是我几年前拼凑出来并在各种项目中使用过的系统调用函数。如果你不想从命令中得到任何输出,只需输入 out = syscmd(command) 然后不对 out 进行任何操作即可。

已经在 Python 2.7.12 和 3.5.2 中测试并且可用。

def syscmd(cmd, encoding=''):
    """
    Runs a command on the system, waits for the command to finish, and then
    returns the text output of the command. If the command produces no text
    output, the command's return code will be returned instead.
    """
    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT,
        close_fds=True)
    p.wait()
    output = p.stdout.read()
    if len(output) > 1:
        if encoding: return output.decode(encoding)
        else: return output
    return p.returncode

0

在使用Python 3.5+时,您还可以使用更新的subprocess.run(...)方法,并传递capture_output=True选项:

import subprocess
subprocess.run(['/etc/init.d/apache2', 'restart'], capture_output=True)

如果您确实想要捕获输出,请参阅文档中使用子进程模块部分中的示例。


0

我认为,当使用 os.system 无法隐藏控制台输出时,最简单的方法是使用 os.popen

os.popen("/etc/init.d/apache2 restart")

0

我在使用Windows机器时遇到了类似的问题,发现这是解决问题最简单的方法。

import subprocess
cmd='gdalwarp -overwrite -s_srs EPSG:4283 -t_srs EPSG:28350 -of AAIGrid XXXXX.tif XXXXX.asc'
subprocess.run(cmd,shell=True)

更改cmd为您想要运行的任何内容。我迭代了1000多次,而没有命令提示窗口出现,我能够节省很多时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接