如何防止不受支持的“shopt”選項在我的 .bashrc 中導致錯誤?
我在一個相對異構的環境中工作,我可能在不同的 HPC 節點、VM 或我的個人工作站上執行不同版本的 Bash。因為我將登錄腳本放在 Git 儲存庫中,所以我想
.bashrc
全面使用相同的(ish),沒有很多“如果這個主機,那麼……”類型的混亂。我喜歡Bash ≤ 4.1 的預設行為,它
cd $SOMEPATH
在按鍵cd /the/actual/path
時會擴展Tab
。在 Bash 4.2 及更高版本中,您需要shopt -s direxpand
重新啟用此行為,並且直到4.2.29才可用。不過,這只是一個例子;另一個可能相關shopt
的選項complete_fullquote
(儘管我不知道它的確切作用)可能也改變了 v4.2 的預設行為。但是,
direxpand
早期版本的 Bash 無法辨識,如果我嘗試shopt -s direxpand
在我.bashrc
的 .-bash: shopt: direxpand: invalid shell option name
我想做的是包裝一個條件,
shop -s direxpand
以一種健壯的方式在 Bash > 4.1 上啟用該選項,而不會惹惱舊版本的 Bash(即,不僅僅是將錯誤輸出重定向到/dev/null
)。
檢查是否
direxpand
存在於的輸出中shopt
,如果存在則啟用它:shopt | grep -q '^direxpand\b' && shopt -s direxpand
我看不出將錯誤重定向到
/dev/null
. 如果您希望您的程式碼具有健壯性set -e
,請使用常見的習慣用法… || true
:shopt -s direxpand 2>/dev/null || true
如果您想在選項不存在的情況下執行一些備份程式碼,請使用以下返回狀態
shopt
:if shopt -s direxpand 2>/dev/null; then … # the direxpand option exists else … # the direxpand option does not exist fi
但是如果你真的不喜歡重定向錯誤,你可以使用完成機制來執行自省。這假設您沒有 bash ≤ 2.03 且沒有可程式完成的過時機器。
shopt_exists () { compgen -A shopt -X \!"$1" "$1" >/dev/null } if shopt_exists direxpand; then shopt -s direxpand fi
這種方法避免了分叉,這在某些環境(例如 Cygwin)上很慢。直截了當的也是如此
2>/dev/null
,我認為您無法在性能上擊敗它。