Bash
有條件地將變數設置為只讀的函式
如果我有一個腳本將變數只讀設置為一些奇數值,並且
errexit
由於其他不安全的操作而設置:#!/bin/bash set -e declare -r NOTIFY=$(case "$OS" in (macosx) echo macos_notify ;; (linux) echo linux_notify ;; (*) echo : ;; esac) declare -r SAY=_say # _say is a function declare -r VERSION=0.99 set +e
我第二次使用它來獲取定義,因為它正在開發中:
$ . s.bash $ . s.bash bash: declare: NOTIFY: readonly variable Exited
通常
declare -r EXISTING_VAR
既不會停止腳本也不會刪除EXISTING_VAR
.但是對於
errexit
,分配給現有變數是可以理解的失敗。簡單的選項是刪除-r
或使用set +e
該部分腳本。除此之外,如果名稱已經存在,是否可以編寫一個 Bash 函式來代替
declare -r
但不重新分配?我試過:
# arg #1: var name, #2: value set_var_once () { # test whether the variable with the # name stored in $1 exists if [[ -z "${!1}" ]] then # if it doesn't, set it declare -r $1=$2 fi }
我也嘗試過類似的東西
eval "declare -r $1=$(eval $2)"
,感覺eval
這裡的某個地方需要,但我不確定在哪裡。所有版本的
set_var_once
結果都沒有設置他們應該設置的變數。
declare -r
使變數只讀,但也在目前範圍內聲明它,因此使其成為目前函式的本地變數。相反,您只希望readonly
前者:readonly_once() { local __assign for __assign do [[ -v ${__assign%%=*} ]] || readonly "$__assign" done }
用作:
readonly_once VAR1=foo VAR2="$(cmd)" PATH ...
請注意,由於與 相反
readonly
,thatreadonly_once
不是關鍵字(是的,即使隱藏了該事實也是關鍵字),因此readonly
需要引用以防止拆分 + glob,此時它不是賦值。bash``$(cmd)
$(cmd)
將被擴展(並因此cmd
執行),即使該值最終不會被分配(VAR2
如果它已經定義)。該函式僅適用於標量變數,不適用於數組或關聯數組。