Lai*_*ain 11 python subprocess os.system
我最近遇到了一些有关堆栈溢出的帖子,说子进程比os.system好得多,但是我很难找到确切的优点.
我遇到的一些例子:https: //docs.python.org/3/library/os.html#os.system
"子进程模块提供了更强大的工具来生成新进程并检索其结果;使用该模块比使用此函数更可取."
不知道它在哪些方面更强大,我知道在很多方面使用子进程更容易,但实际上它在某种程度上更强大吗?
另一个例子是:
子进程与系统的优点是它更灵活(你可以得到stdout,stderr,"真正的"状态代码,更好的错误处理等等).
这篇帖子有2600多张选票.再一次找不到更好的错误处理或真实状态代码意味着什么.
该帖子的最高评论是:
无法理解为什么你使用os.system即使是快速/脏/一次性.子进程看起来好多了.
同样,我理解它使一些事情稍微容易些,但我几乎无法理解为什么例如:
subprocess.call("netsh interface set interface \"Wi-Fi\" enable", shell=True)
Run Code Online (Sandbox Code Playgroud)
比任何更好
os.system("netsh interface set interface \"Wi-Fi\" enabled")
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释一些它更好的原因吗?
Mat*_*lia 16
首先,你正在切断中间人; subprocess.call默认情况下,避免生成检查命令的shell,并直接生成请求的进程.这很重要,因为除了问题的效率方面,你没有太多的控制默认的shell行为,它实际上通常对你有所逃避.
特别是,通常你永远不会这样做:
subprocess.call("netsh interface set interface \"Wi-Fi\" enable")
Run Code Online (Sandbox Code Playgroud)
以来
如果传递单个字符串,则
shell必须是True(见下文),否则字符串必须简单地命名要执行的程序而不指定任何参数.
相反,你会做:
subprocess.call(["netsh", "interface", "set", "interface", "Wi-Fi", "enable"])
Run Code Online (Sandbox Code Playgroud)
请注意,这里所有逃脱的噩梦都消失了.subprocess处理转义(如果操作系统想要将参数作为单个字符串 - 例如Windows)或将分离的参数直接传递给相关的系统调用(execvp在UNIX上).
相比之下,必须自己处理转义,尤其是跨平台方式(cmd不会像POSIX一样逃脱sh),尤其是中间的shell搞乱你的东西(相信我,你不想要知道什么是邪恶的混乱,为你的命令提供100%安全的逃避呼叫cmd /k).
此外,subprocess在中间没有外壳的情况下使用时,您确定获得了正确的返回代码.如果启动该过程失败,则会出现Python异常,如果获得返回代码,则实际上是已启动程序的返回代码.随着os.system你没有办法知道,如果你得到的返回码来自启动命令(通常是,如果外壳设法启动它的默认行为),或者是从外壳的一些错误(如果它没能启动它).
除了参数拆分/转义和返回代码之外,您还可以更好地控制已启动的进程.即使使用subprocess.call(这是功能上最基本的实用功能subprocess),您也可以重定向stdin,stdout并stderr可能与已启动的进程通信.check_call类似,它避免了忽略失败退出代码的风险.check_output涵盖了将check_call所有程序输出捕获到字符串变量中的常见用例.
一旦你过去call和朋友(这就像阻塞一样os.system),就会有更强大的功能 - 特别是,Popen对象允许你异步地使用已启动的进程.你可以启动它,可能通过重定向的流与它通信,检查它是否正在运行,同时做其他的东西,等待它完成,向它发送信号并杀死它 - 除了光之外的所有东西同步"启动进程与默认stdin/stdout/stderr通过shell并等待它完成" os.system提供.
所以,总结一下,用subprocess:
call和朋友),你:
Popen:
鉴于这种subprocess做法不仅os.system可以做到 - 而且更安全,更灵活(如果你需要)的方式 - 没有理由使用它system.
原因有很多,但主要原因直接在docstring中提到:
>>> os.system.__doc__
'Execute the command in a subshell.'
Run Code Online (Sandbox Code Playgroud)
对于几乎所有需要子进程的情况,都不希望生成子shell.这是不必要的和浪费的,它增加了额外的复杂性,并引入了几个新的漏洞和故障模式.使用subprocess模块切断了中间人.  
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           5988 次  |  
        
|   最近记录:  |