[Linux] 標準輸入、標準輸出和標準錯誤輸出
Posted On 2019-05-02
名稱 | 類型 | 描敘符號 | 操作 |
---|---|---|---|
標準輸入-stdin | Standard input | 0 | <, << |
標準輸出-stdout | Standard output | 1 | >, >> |
標準錯誤輸入-stderr | Standard error ouput | 2 | 2>, 2>> |
通常我們可以在從螢幕上看到這些輸入和輸出,但是某些情況下會希望這些資料可以導入到一個檔案中,以便日後的查詢和檢查,尤其是透過crontab執行的程式,下面是利用shell和python程式的例子,
#!/bin/bash
echo "This is an Error" >&2
echo "This is normal output"
#!/usr/bin/env python
#encoding=utf-8
from __future__ import print_function
import sys
if __name__ == '__main__':
print("Output to stdout")
print("Output to stderr", file=sys.stderr)
重新導向的符號>
在指令中的哪一個位置都沒有太大的關係,不過要注意重新導向的順序一定是從左到右,例如:
# 下面結果相同
>&2 ls test
ls >&2 test
ls test >&2
# & what comes next is a file descriptor, not a file (only for right hand side of >)
重新導向的範本如下:
# 把stderr導入test.log當中,螢幕則顯示標準輸出
./test.sh 2> test.log
python3 test.py 2> test.log
# 標準輸出寫入到檔案test.log,標準錯誤輸出直接列印在螢幕
./test.sh > test.log
./test.sh 1> test.log
python3 test.py > test.log
python3 test.py 1> test.log
# 把stdout寫入到test1.log當中,stderr寫入到test2.log當中
python3 test.py 1> test1.log 2> test2.log
python3 test.py > test1.log 2> test2.log
# 把stderr綁定到stdout中,再透過>導入test.log當中
./test.sh > test.log 2>&1
python3 test.py > test.log 2>&1
# &> file,這個代表stdout和stderr都重定向到 file,與上一個命令同樣效果( &>是bash當中的縮寫用法,用在其他shell上可能會無法使用,推薦還是上面的2>&1比較正規),另外 &> 或 >& 效果是一樣的
python3 test.py &> test.log
python3 test.py >& test.log
# stdout重定向到 /dev/null (相當於拋棄所有stdout輸出)
python3 test.py > /dev/null
不管是python或是shell基本上都是一樣的,另外下面的情況不推薦使用
# 標準輸出和標準錯誤輸出都寫入到test.log,會出現互相覆蓋的問題,正常情況不推薦這樣使用
python3 test.py > test.log 2> test.log
特殊情況
比較一下python3 test.py 2>&1 > test.log
和python3 test.py > test.log 2>&1
的區別:
# python3 test.py 2>&1 > test.log
# 會發現 2>&1 的時候,只是把標準錯誤輸出重導向到了標準輸出,而此時標準輸出的預設值是螢幕,因此實際等於標準錯誤輸出被重定向到了螢幕,而非檔案。因此重定向需要注意順序。
這邊標準錯誤輸出會顯示在螢幕上,而標準輸出則是存入的檔案內
# python3 test.py > test.log 2>&1
這邊標準輸出和標準錯誤輸出都會存入檔案內
Reference
echo >&2 “some text” what does it mean in shell scripting
What are the shell's control and redirection operators?