変数を条件付きで読み取り専用に設定する機能

変数を条件付きで読み取り専用に設定する機能

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 ...

とは異なり、readonlythatはreadonly_onceキーワードではありません(たとえばreadonly返品キーワードはbashこの事実を隠しますが)$(cmd)分割+グローブを避けるために引用する必要があり、この場合は割り当てではありません。

$(cmd)cmd値が最終的に割り当てられていなくても(VAR2定義されている場合)、拡張されます(したがって実行されます)。

この関数は、配列や連想配列ではなく、スカラー変数でのみ機能します。

おすすめ記事