今天來講講打完指令在螢幕上顯示的東西吧。
首先,會出現在終端機畫面上的資訊,有兩種:
stdout
stderr
stdout 通常用來輸出一般的資訊, stderr 通常則用來輸出錯誤資訊(但是有利外)。下面舉的例子吧:
因為 find 指令進不去 folder3 所以有一個錯誤訊息。那 stdout 跟 stderr 有差嗎?反正都是顯示在終端機上不是嗎?
平常確實沒有什麼差異,但是如果今天我們透過輸出重新定向 > ,把指令的結果輸出到檔案呢:
注意到了嗎,加上重新定向符號 > 後, find: ‘./folder3’: 拒絕不符權限的操作 這行依然顯示在螢幕上,沒有被存進去 myFileLocation.txt 。如果要把 stderr 的結果輸出到檔案,要用 2> 來把它輸出到檔案:
find -name myFile > myFileLocation.txt 2> myFileLocation-Error.txt
執行這個指令後,你會發現終端機上聯錯誤訊息都沒有顯示,而且錯誤訊息也真的被存在 myFileLocation-Error.txt 裡面:
當然如果你不希望覆蓋掉原本的檔案,可以用 >> 來取代 > ,也就是開啟檔案時,是 a 模式還是 w 模式。
不過有沒有例外?當然有,像是 ffmpeg 常常會需要把檔案解碼後,丟給下一隻程式像是 x264 處理,這時候 stdout 就會被拿來輸出解碼後的內容,而 stderr 則顯示檔案編碼進度。
至於把程式執行後的 stdout 丟到下一隻程式的方法,應該也有不少人用過: | ,像是 cat /etc/passwd | grep dd-han 就會把 cat /etc/passwd 的執行結果(也就是整個 passwd 檔案的內容)透過 stdin 丟到 grep , grep 則會找出有 dd-han 的那行顯示出來。
那如果要把變數丟進去指令的 stdin 呢?
echo $MYVAR | grep dd-han
這是一種作法,不過這個作法有個問題,如果你的 MYVAR 內容是 -n ,因為 echo 本身可以下 -n 所以最後什麼都不會輸出。在這裡建議用另一種作法:
grep dd-han <<< $MYVAR
<<< 可以用在比較新的 Bash 與 Zsh ,如果你是比較舊版的 bash 或是要用在 sh 上,可以用下面的方法代替:
grep dd-han << EOF
$MYVAR
EOF
回到最前面的 find ,有時候 find 過程中,錯誤比結果還多,根本幫倒忙,這種時候也可以這樣下指令:
find -name myFile 2> /dev/null
反正進不去的資料夾我也沒興趣知道,直接導向 /dev/null 就看不到啦。
今天就這樣吧,遊戲還沒打先閃。
我是誰?
我是 dd-han ,可以叫我呆翰,是國立臺中科技大學的延畢生 與 創科資訊的時習生。