bash 中的 exec 重定向
我編寫了很多非互動式腳本,我希望所有輸出都轉到日誌文件並且螢幕上沒有任何內容。
為了解決這個問題,我一直在使用:
#!/bin/bash exec &> logfile echo "Step One:" /some/command/one echo "Step Two:" /some/command/two
我想確保這是一種理智的方法。
如果我繼續採用這種方法,是否會遇到任何重大的缺點或問題?如果是這樣,它們是什麼以及如何最好地減輕它們(包括通過改變我的方法)。
將命令輸出重定向到日誌文件
將所有命令輸出(包括錯誤消息)重定向到日誌文件是非互動式 shell 腳本的標準做法。記錄由 cron 執行或由其他外部事件觸發的腳本的命令輸出記錄特別有用,並且在此類案例中沒有缺點。
我的許多 shell 腳本在開頭附近都包含以下幾行:
exec 1>>"$logfile" exec 2>&1
這些重定向命令的順序很重要。第一個
exec
命令將所有寫入重定向到stdout
(1) 流以將 (>>
) 附加到日誌文件。第二個命令將所有對 (2) 流的寫入重定向到(1) 目前指向stderr
的相同文件描述符。stdout
僅使用一個文件描述符來訪問文件可確保寫入以所需的順序發生。如果使用 Bash,您可以將這些命令組合成一個執行相同操作的構造:
exec &>>"$logfile"
如果您希望在每次執行腳本時清除日誌文件中的先前條目,請僅使用單個
>
重定向運算符(覆蓋先前的內容):exec &>"$logfile"
用於輸入/輸出重定向的內置函式由Shell 命令語言
exec
的 POSIX 定義指定,並且該內置函式在任何 POSIX 兼容的 shell 中都可用。exec
執行互動式 shell 時的重定向
您可以在臨時/一次性互動式 shell 會話中嘗試將標準輸出重定向到文件。執行後
exec 1>outfile
,所有未來的命令都將其輸出列印outfile
到終端而不是終端。您還可以在互動式 shell 會話中嘗試重定向標準錯誤,但這會使互動式 shell 很難使用:
執行後
exec 2>errorfile
,任何其他命令產生的標準錯誤都會寫入重定向的錯誤文件 - 正如預期的那樣。但是,問題是從現在開始,shell(在這種情況下為 Bash)將其提示列印到此文件,並且作為命令鍵入的任何文本也將重定向到此文件。一些 shell(例如 Bash)也會回顯 to 接收stdin
到的字元stderr
。其他的,例如dash
對於 shell 會話的其餘部分,你基本上是在盲目地工作,因為沒有任何東西被發送到終端,這顯然使得繼續與 shell 互動變得非常困難。正如 Orion 指出的那樣,您可以在分別使用和嘗試任何此類實驗之前儲存對預設
stdout
和stderr
文件描述符的引用。完成實驗後,您可以通過執行將列印恢復為標準錯誤並將列印恢復為標準輸出。exec 3>&1``exec 4>&2``exec 2>&4``exec 1>&3
對於互動式使用,我建議在逐個命令的基礎上重定向標準輸出和標準錯誤流:
>>outfile 2>&1 command with arguments
.