Bash
Bash:抑制後重新打開stderr
我製作了這個腳本,它可以自動安裝/解除安裝 git。在我的測試是否安裝了 git 的函式中,我使用
git --version
命令並測試返回碼。我不喜歡正常出現的 stderr 輸出,因為我正在嘗試製作一個不錯的自定義輸出。儘管我已經想出瞭如何僅為此功能抑制 stderr,但我似乎無法重新啟動它。
呼叫此函式後,我的
read
提示現在失去了。function CheckGit() { exec 3>&2 # link file desc 3 w/ stderr exec 2> /dev/null SILENT_MODE=$1 if [[ ! $(git --version) ]]; then if [ SILENT_MODE ]; then printf "${LT_RED} GIT IS NOT INSTALLED.\n" fi continue; else if [ SILENT_MODE ]; then printf "${LT_BLUE} GIT IS CURRENTLY INSTALLED.\n" fi continue; fi GIT_INSTALLED=$? #turn back on the stderr notifications exec 2>&3 3>&- # Restore stdout and close file descriptor #3 } while true; do printf "${LT_BLUE} Menu\n" printf " ***********************************************\n" printf "${LT_GREEN} a) Check git.\n" printf "${LT_GREEN} b) (More to be added)\n" printf "${LT_GREEN} c) ...\n" printf "${LT_GREEN} d) ...\n" printf "${LT_GREEN} h) ...\n" printf "${LT_RED} x) Exit.\n" printf "\n${NC}" read -p "Please make a selection: " eotuyx case $eotuyx in [Aa]* ) CheckGit true; continue;; [Bb]* ) ...; continue;; [Cc]* ) ...; continue;; [Dd]* ) ...; continue;; [Hh]* ) ...; continue;; [XxQq]* ) break;; * ) -e "\n${NC}" + "Please answer with a, b, c, d, x(or q).";; esac done
重申評論中給出的建議:
- 從函式中
刪除
continue
語句。CheckGit
- 它們不是必需的,
- 而且——你可能沒有意識到——它們不僅會導致(從函式)立即返回到主循環,而且會立即返回到
while true
主循環頂部的語句。因此,正如Tomasz 指出的那樣,您的exec 2>&3 3>&-
語句沒有被執行。一般注意事項:
if [ SILENT_MODE ]
正如mosvy 指出的那樣,它總是正確的,因為它只是測試字元串SILENT_MODE
是否為非空。你似乎想要if [ "$SILENT_MODE" ]
。- 但你可能在自欺欺人。
if [ "$SILENT_MODE" ]
是真的,即使$SILENT_MODE
是false
——它所做的只是測試字元串是否為非空,所以呼叫CheckGit false
仍然會導致資訊被顯示。- 而且,即使您沒有欺騙自己,您也可能欺騙了下週必須維護此腳本的人。而且,是的,那個人可能就是你。您的明顯邏輯是“如果處於靜默模式,請報告額外資訊”。這在邏輯上是倒退的;說起來會更有意義
if [ "$SILENT_MODE" = false ]
,或者呼叫變數VERBOSE_MODE
。$?
非常短暫。它始終是最新命令的結果。 所以,如果你這樣做if *檢查是否安裝了 git*;然後 printf "GIT 未安裝。\n" 別的 printf "GIT 已安裝。\n" 是 GIT_INSTALLED=$?
然後
GIT_INSTALLED
獲取printf
. 您需要提前設置GIT_INSTALLED
。 6. 您的測試,,if [[ ! $(git --version) ]]; then
測試,而不是“返回碼”(正如您在問題中所說),而是是否git --version
將任何內容寫入標準輸出。這可能是你想要的。這可能是測試是否git
安裝的最佳方法。但是檢查命令的退出狀態可能會更好(通常通常更好)。 7. 風格說明:如果“真實”部分在前,我發現if
-then
-else
陳述更容易理解。你的腳本說如果沒有安裝 git 然後 說沒有安裝 否則(即,如果***未***安裝) 說它已安裝 是
雙重否定令人困惑。 8. 而且,是的;
exec 2> /dev/null
如果您想從連續 42 條語句中抑制標準錯誤,這很方便。如果您只需要影響單個命令,只需將2> /dev/null
(或> /dev/null 2>&1
)放在該命令上,就像mosvy 建議的那樣。