[英]Suppress output in Python calls to executables
我有一个名为A
的二进制文件,它在调用时生成输出。 如果我从Bash shell调用它,大多数输出都被A > /dev/null
抑制。 所有输出都被A &> /dev/null
抑制
我有一个名为B
的python脚本需要调用A
我希望能够从B
生成输出,同时抑制A
所有输出。
从B
,我尝试过os.system('A')
, os.system('A > /dev/null')
和os.system('A &> /dev/null')
, os.execvp('...')
等,但没有一个压制A的所有输出。
我可以运行B &> /dev/null
,但这也会抑制B
的所有输出,我不希望这样。
有人有建议吗?
import os
import subprocess
command = ["executable", "argument_1", "argument_2"]
with open(os.devnull, "w") as fnull:
result = subprocess.call(command, stdout = fnull, stderr = fnull)
如果命令没有任何参数,则可以将其作为简单字符串提供。
如果您的命令依赖于通配符,管道或环境变量等shell功能,则需要将整个命令作为字符串提供,并指定shell = True
。 但是,应该避免这种情况,因为如果不仔细验证字符串的内容,则表示存在安全隐患。
如果你有Python 2.4,你可以使用子进程模块 :
>>> import subprocess
>>> s = subprocess.Popen(['cowsay', 'hello'], \
stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
>>> print s
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
在Python 3.3及更高版本中, subprocess
支持重定向到/dev/null
的选项 。 要使用它,在调用.Popen
和朋友时,请将stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
.Popen
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
.Popen
指定为关键字参数。
所以DNS的答案,为Python 3.3+重写,变成了
import subprocess
command = ["executable", "argument_1", "argument_2"]
result = subprocess.call(command,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
从文档:
subprocess.DEVNULL¶
可以用作Popen的stdin,stdout或stderr参数的特殊值,表示将使用特殊文件os.devnull。
版本3.3中的新功能。
对于Python 3.0到3.2,您必须使用open(os.devnull)
手动打开空设备,如DNS所写。
如果您的搜索引擎引导您回到这个老问题(像我一样),请注意使用PIPE可能会导致死锁 。 实际上,因为管道是缓冲的,所以即使没有人读取它,你也可以在管道中写入一定数量的字节。 但是缓冲区的大小是有限的。 因此,如果您的程序A的输出大于缓冲区,则A将在写入时被阻止,而调用程序B等待A的终止。 但是,在这种特殊情况下...请参阅下面的注释。
不过,我建议使用Devin Jeanpierre和DNS的解决方案。
正如os.system()文档所提到的,使用子进程模块,如果你愿意,在打开子进程时设置stdout = open(os.devnull,'w')(对于stderr也可能是相同的)。
我知道这是游戏的后期,但为什么不简单地从os.system中将输出重定向到/ dev / null? 例如:
tgt_file = "./bogus.txt"
os.sytem("d2u '%s' &> /dev/null" % tgt_file)
这似乎适用于那些你不想处理subprocess.STDOUT的情况。
如果您不想等待命令完成,例如启动备份任务,则另一个选项是通过bash传递它,这样做可以使重定向正常运行。
例如,使用aplay启动声音文件:
import os
def PlaySound(filename):
command = 'bash -c "aplay %s &> /dev/null &"' % (filename)
os.system(command)
这样我就可以生成一个新进程,而不是等待它完成并阻止它打印到终端。 唯一的问题是,它将加载一个bash实例以及您正在运行的进程,从而提供轻微的开销。
我用:
call(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
其中command是命令+参数的字符串
为此,您必须导入子进程
如果你需要捕获STDOUT,不将它分配给变量吗? 例如:
megabyte=''
# Create a 1 MiB string of NULL characters.
for i in range(1048576):
megabyte += '\0'
fh=open('zero.bin','w')
# Write an 8 GiB file.
for i in range(8192):
print(i)
# Suppress output of 'write()' by assigning to a variable.
discard=fh.write(megabyte)
fh.close()
我正在创建一个大的零填充文件,以便在我的硬盘上零空闲空间,并发现每次调用handle.write(string)都会吐出写入的字节数。 将其分配给可修复的输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.