Linux中重定向應注意的事情

王bourne發表於2023-05-08

引言

你是否見過bash ... 2>&1 1>file.txt的寫法? 還沒發現這樣的寫法有什麼問題? 那麼恭喜你, 看完本文你又將學會一個新知識!

重定向的錯誤用法

以引言中命令為例, 2>&1表示將錯誤輸出重定向到標準輸出, 1>file.txt表示將標準輸出重定向到file.txt檔案, 看起來的意思就是將標準輸出和錯誤輸出全都重定向到file.txt?

錯啦! 上述命令只會標準輸出重定向到file.txt檔案, 而錯誤輸出還是重定向到終端(或者叫做命令列, 控制檯, 螢幕). 因為首先解析的是2>&1,此時的1指向的還是標準輸出, 即終端, 解析到1>file.txt時, 標準輸出才被重定向到file.txt. 下面我將用一個例子來驗證我的結論:

test.sh是一個簡單的指令碼, 會把STDOUT輸出到標準輸出, 將STDERR輸出到錯誤輸出

$ cat test.sh
echo 'STDOUT' >&1
echo 'STDERR' >&2

我們先驗證指令碼的正確性, 標準輸出和錯誤輸出都被正確的捕捉到了, 指令碼可以同時輸出標準輸出和錯誤輸出, 正確性得以驗證.

現在我們再來驗證我一開始的結論, 執行bash ... 2>&1 1>file.txt形式的命令, 可以看到錯誤輸出STDERR被輸出到了終端, 而file.txt中僅有標準輸出STDOUT

那麼應該怎麼改成我們想要的結果呢? 很簡單, 將2>&1和1>file.txt調換個位置即可, 即bash ... 1>file.txt 2>&1; 或者使用bash ... &>file.txt, 都可以達到我們想要的效果

重定向另外一個值得注意的事項

重定向另外一個需要注意的事項就是: 執行類似於command > file.txt的命令時, 會首先判斷file.txt是否存在, 若存在則先清空檔案, 若不存在則建立檔案, 隨後才會執行command

假設有一個已經排好序的檔案file.txt, 我們對這個檔案去重的話, 執行uniq file.txt > file.txt會直接清空檔案

想要不生成額外的臨時檔案做到去重的話, 正確的做法應該是使用管道|配合tee命令, 而不是使用重定向

相關文章