隐藏os.system生成的控制台输出

Are*_*ski 10 python shell

我正在调用这段代码,但它在我运行python脚本的控制台中产生一些输出(由于tee命令):

os.system("echo 3 | sudo tee /proc/sys/vm/drop_caches")
Run Code Online (Sandbox Code Playgroud)

这个版本不会产生控制台输出,但有另一种方式吗?

os.system('sudo bash -c "echo 3 > /proc/sys/vm/drop_caches"')
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 10

要以最通用的形式回答基于其标题的问题:

禁止所有输出os.system(),请附加>/dev/null 2>&1到shell命令,这会使stdout和stderr静音 ; 例如:

import os
os.system('echo 3 | sudo tee /proc/sys/vm/drop_caches >/dev/null 2>&1')
Run Code Online (Sandbox Code Playgroud)

请注意,os.system()通过设计将输出传递给调用进程'stdout和stderr流 - 您的Python代码永远不会看到它们.

此外,如果shell命令失败并且返回退出代码,os.system()不会引发异常; 请注意,提取shell命令的真正退出代码需要额外的工作:您需要通过应用从返回的16位值中提取高字节>> 8(尽管您可以依赖于0隐含错误条件之外的返回值).


鉴于上述限制os.system(),通常值得使用subprocess模块中的函数:

例如,subprocess.check_output()可以使用如下:

import subprocess
subprocess.check_output('echo 3 | sudo tee /proc/sys/vm/drop_caches', shell=True) 
Run Code Online (Sandbox Code Playgroud)

以上将:

  • 捕获stdout输出并返回它(在上面的例子中忽略返回值)
  • 传递stderr输出; stderr=subprocess.STDOUT作为附加参数传递也会捕获stderr.
  • 如果shell命令失败,则引发错误.

注意:Python的3.5推出subprocess.run(),更灵活的继任者都os.system()subprocess.check_output()-看到https://docs.python.org/3.5/library/subprocess.html#using-the-subprocess-module


注意:

  • OP首先使用的原因tee- 尽管对stdout输出不感兴趣 - 是一个天真的尝试使用> ...而不是 sudo被调用之前被解释,因此失败,因为写入的所需特权/proc/sys/...没有被已经批准了.
  • 无论您是使用函数os.system()还是subprocess函数,stdin都不会受到默认设置的影响,因此如果您从终端调用脚本,sudo则在遇到命令时会收到交互式密码提示(除非已缓存凭据).


Ala*_*ack 5

直接写入 proc 伪文件,而不是通过 Python i/o lib。

这将要求您的脚本以 root 身份(通过sudo)运行,这意味着您应该将其范围限制为仅限管理员使用的工具。这也允许脚本在sudo需要密码的盒子上运行。

例子:

with open("/proc/sys/vm/drop_caches", "w") as drop_caches:
    drop_caches.write("3")
Run Code Online (Sandbox Code Playgroud)

  • @Petesh,如果脚本需要 root 权限才能运行,那么用户必须了解风险。在“sudo”需要密码的系统上,OP 的原始脚本将失败。要求用户“sudo”我的代码,会使风险和意图非常明显。 (2认同)