2015-09-25 82 views
1

我從https://pymotw.com/2/subprocess/Python的與子「1>&2」和stderr = STDOUT

這個代碼我不知道如何解釋的代碼,在check_output1>&2輸出重定向到stderr,但在參數,stderr返回標準輸出stderr=subprocess.STDOUT

output = subprocess.check_output(
    'echo to stdout; echo to stderr 1>&2; exit 1', 
    shell=True, 
    stderr=subprocess.STDOUT, 
    ) 
print "*****************" 
print 'Have %d bytes in output' % len(output) 
print output 

運行代碼,打印命令不執行沒啥意思被捕獲。

是什麼代碼試圖完成?當我註釋掉stderr=subprocess.STDOUT

***************** 
Have 20 bytes in output 
to stdout 
to stderr 

不過,我:

編輯

從答案和評論,我可以運行該代碼來獲得

try: 
    output = subprocess.check_output(
     'echo to stdout; echo to stderr 1>&2; exit 1', 
     shell=True, # No such file or directory error without, maybe 1>&2 requires shell=True 
     stderr=subprocess.STDOUT, 
     ) 

except subprocess.CalledProcessError as e: 

    print "*****************" 
    print 'Have %d bytes in output' % len(e.output) 
    print e.output 

這個輸出有代替

to stderr 
***************** 
Have 10 bytes in output 
to stdout 

EDIT2

我測試了更多的stderr庫(https://github.com/sickill/stderred),它可以幫助shell以紅色顯示stderr中的字符。

當我執行這個代碼(註釋掉重定向),我可以看到黑色的,這意味着它使用標準輸出的to stderr

output = subprocess.check_output(
     'echo to stdout; echo to stderr 1>&2; exit 1', 
     shell=True, 
     #stderr=subprocess.STDOUT, 
     ) 

由此,我猜(糾正我,如果我錯了)Python的check_output方法打印出來的數據爲標準錯誤重定向到標準輸出,使其打印出錯誤信息到標準錯誤。

enter image description here

回答

2

1 >&2殼碼只適用於(回波)它出現在命令。這是如何告訴shell將該echo的輸出指向shell的stderr流。

python代碼stderr=subprocess.STDOUT告訴子進程模塊,您希望進程的stderr流與其stdout流相同的文件描述符,以便您可以讀取任何進程寫入的流或者將流交錯在一起的流。

在外殼命令的exit 1意味着該外殼退出並顯示錯誤(非零)的狀態。

代碼的目的是要證明,蟒蛇功能subprocess.check_output將檢查退出狀態,並拋出一個異常時,它是非零。

如果退出代碼爲非零,則會引發CalledProcessError。 CalledProcessError對象將在returncode屬性中具有返回碼,並在輸出屬性中輸出。

你的描述:

運行代碼,打印命令不執行

是有點誤導,因爲你忘了提及確實發生了輸出:

Traceback (most recent call last): 
    File "t.py", line 6, in <module> 
    stderr=subprocess.STDOUT, 
    File "/usr/lib/python2.7/subprocess.py", line 573, in check_output 
    raise CalledProcessError(retcode, cmd, output=output) 
subprocess.CalledProcessError: Command 'echo to stdout; echo to stderr 1>&2; exit 1' returned non-zero exit status 1 
+0

即使我刪除了所有三個打印命令,我也得到了相同的輸出,所以我非常肯定打印命令是* n ot *執行。 – prosseek

+2

@prosseek:是的,如果發生異常,除非你抓住它;不執行'print'語句,這是異常如何工作的 - 它們中斷正常的程序流。你可以添加'try:check_output(...),除了CalledProcessError爲e:print('例外:%s,捕獲的輸出:%s'%(e,e.output))' – jfs