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
2番目に開発中なので定義を得ました。
$ . s.bash
$ . s.bash
bash: declare: NOTIFY: readonly variable
Exited
通常、declare -r EXISTING_VAR
スクリプトを停止したり、古いジョブ定義を削除したりしませんEXISTING_VAR
。
ただし、この場合、errexit
既存の変数への割り当ては当然失敗します。簡単なオプションは、スクリプトの適切な部分を削除-r
または使用することです。set +e
他にも、declare -r
名前がすでに存在する場合は、置き換えられますが再割り当てできないBash関数を書くことはできますか??
私は試した:
# 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
では、変数が必要な場所に設定されていません。
ベストアンサー1
declare -r
変数を読み取り専用にするだけでなく、主張する現在のスコープにあるので、現在の関数にローカルに作成します。あなたが望むのはreadonly
電子です。
readonly_once() {
local __assign
for __assign do
[[ -v ${__assign%%=*} ]] || readonly "$__assign"
done
}
次のように使用されます。
readonly_once VAR1=foo VAR2="$(cmd)" PATH ...
とは異なり、readonly
thatはreadonly_once
キーワードではありません(たとえばreadonly
、返品キーワードはbash
この事実を隠しますが)$(cmd)
分割+グローブを避けるために引用する必要があり、この場合は割り当てではありません。
$(cmd)
cmd
値が最終的に割り当てられていなくても(VAR2
定義されている場合)、拡張されます(したがって実行されます)。
この関数は、配列や連想配列ではなく、スカラー変数でのみ機能します。