2016-02-29 65 views
1

[编辑]
subprocess.Popen处理标准输出的2个选项是stdout="a_file_name"stdout=subprocess.PIPE
stderr可以通过stderr=subprocess.STDOUT与其中任何一个组合。对于subprocess.stderr = STDOUT - stdout = PIPE比stdout =“a_file_name”更好吗?

对于我目前正在做的(模糊测试),我的结果stdout="a_file_name"代码稍短且更干净。

但是,从我所看到的,似乎stdout=PIPE往往是其他人的首选,但我不确定所有原因为什么。

如果Popen([cmd, arg], ...)使用的cmd是错误输出写入stderr外部可执行文件,是stdout=PIPE某种程度上比stdout="a_file_name"更好?

各有什么优点和缺点?

  • 在我的特定情况下(见下面的代码片段),1个优势,我可以看到使用stdout=PIPE而不是stdout="a_file_name"在于,前者可以让我轻松地跳过写一个空文件。
  • 在发生cmd崩溃事件时,2中的1会以某种方式更容易得到所有错误输出?

虽然我有我的特定背景,但我也很想知道更一般情况下的答案。

为了更好地解释我的上下文,这里是我的2替代代码​​段:

import subprocess 
import sys 

assert sys.version_info >= (3, 3) 
    # timeout added for subprocess's wait() and communicate() in Python 3.3. 

with open('sub_proc1.outerr', 'w') as f_outerr1: 
    sub_proc1 = subprocess.Popen([cmd, args], stdout=f_outerr1, 
           stderr=subprocess.STDOUT, 
           universal_newlines=True) 
    try: 
     return_code = sub_proc1.wait(timeout=10) 
     print('*** %s CRASHED with return code: %d.' % (cmd, return_code)) 
    except subprocess.TimeoutExpired: 
     print('*** %s succeeded.' % cmd) 
     sub_proc1.kill() 

与:

... 
with open('sub_proc2.outerr', 'w') as f_outerr2: 
    sub_proc2 = subprocess.Popen([cmd, args], stdout=subprocess.PIPE, 
           stderr=subprocess.STDOUT, 
           universal_newlines=True) 
    try: 
     (sub_proc2_out, sub_proc2_err) = sub_proc2.communicate(timeout=10) 
     print('*** %s CRASHED with return code: %d.' % 
       (cmd, sub_proc2.poll())) 
     assert sub_proc2_err is None 
      # Since stderr was redirected to STDOUT, this should be None. 
     f_outerr2.write(str(sub_proc2_out or "")) 
      # Treat 'None' as an empty string). 
    except subprocess.TimeoutExpired: 
     print('*** %s succeeded.' % cmd) 
     sub_proc2.kill() 

原贴:

标题:子:优点和缺点stderr = STDOUT与stderr = PIPE?

从 'subprocess.Popen' 处理错误输出的2个主要替代似乎是 '标准错误= STDOUT'(与 '标准输出= “SOME_FILE”')和 '标准错误= PIPE'。

对于我想要做的(模糊测试),我的结果'stderr = STDOUT' 代码有点短而且更干净。

但是,从我所读到的看来,'stderr = PIPE'是 首选,但我不确定所有原因。

如果“加利福尼亚”所使用的是其误差输出 写入“stderr的”外部的可执行文件,什么是使用“标准错误= STDOUT” 与“标准错误= PIPE”的利弊?

...

+0

如果您在测试程序中没有对输出进行任何操作(写入文件除外),我认为这两个代码之间没有太大区别。如果您想查看输出的实际细节(例如将其包含在您的'print'调用中,或者检查它是否写出特定的字符串),那么使用'PIPE'将是必要的。第一个代码的一个可能的优点是,如果正在运行的程序交替写入它们,它将交错stdout和stderr流。另一方面,你不能分辨出两个输出! – Blckknght

+0

谢谢你的有用评论,Blckknght。 如果我想检查输出的实际细节,我可以看到PIPE会是更好的选择。 在我的特殊情况下,使stdout和stderr流交错很好。 – Russell

+0

您的评论让我意识到以前没有意识到的东西。 这种交错可以与任一方法: 标准输出= “a_file_name”,标准错误= subprocess.STDOUT 或 标准输出= subprocess.PIPE,标准错误= subprocess.STDOUT 类似地,具有所述stdout和sterrr流非交错是也可以用以下任一方法: stdout =“file_name_1”,stderr =“file_name_2” 或 stdout = subprocess.PIPE,stderr = subprocess.PIPE – Russell

回答

1

写入特定文件意味着如果您的程序每次运行多次都会发生冲突,因为两个进程都希望写入同一个文件。 (搜索临时文件创建和安全漏洞的问题)

使用管道意味着不存在文件名唯一性问题。

你关心输出吗?如果不是,则使用subprocess.DEVNULL,它会为您丢弃输出。

+0

感谢您的回答dsh。 我可以看到写入特定文件可能会导致名称冲突。 不过,我的脚本根据当前日期/时间将其所有输出写入子文件夹,所以这不应该是一个问题: 'out_fdr = time.strftime(os.path.join(' %Y','%m','%d','%H.%%M.%S'))' 我确实关心输出。 到目前为止,我从我的.outerr文件中获得了一些有用的信息,例如: 内存不足 或 虚假内存分配大小 – Russell

+0

如果它在同一秒内运行两次,则会在目录上产生名称冲突:)。如果你想保存输出供将来使用,那么文件更合适。如果你想在你的程序中处理输出,那么管道更自然。 – dsh

+0

这是一个大加。 我的PDF模糊测试通常发现碰撞<1%的时间,而PIPE将让我只写一个stderr输出文件,如果: 1.有stderr输出要写入。 AND 2.发生崩溃。 [原本我用stderr =“a_file_name”,然后删除文件,如果它是空的或没有崩溃。] 谢谢。 – Russell