しますdeclare -a A
空の配列A
をbashに作成しますか、それともA
が後で割り当てられる場合に属性を設定するだけですか?
このコードを考えてみましょう:
set -u
declare -a A
echo ${#A[*]}
echo ${A[*]}
A=()
echo ${#A[*]}
echo ${A[*]}
A=(1 2)
echo ${#A[*]}
echo ${A[*]}
期待される出力は何ですか?
Bash 4.3.48(1)ではbash: A: unbound variable
declare
の後の要素数を照会する場合。また、すべての要素にアクセスするとエラーが発生します。それ以降のバージョンのBashでは、これが異なる方法で処理されることを知っています。それでも、declare
が実際にdefines変数(空にする)であるかどうかを知りたいです。
これは、対応する変数が現在のスコープ(トップレベル、つまりグローバル関数または現在の関数)ですでに宣言されているかどうかによって異なります。
現在のスコープで宣言されていない場合(そして、最上位のスコープでは、変数にdeclared(および割り当てられている)が環境からインポートされている可能性があります)、宣言します(関数スコープ内にある場合、関数に対してローカルにします)、型を割り当てますが、それを初期化しません。空のリストにもしません(_declare -p a
_は_declare -a a
_を示しますが、declare -a a=()
ではありませんa=()
)を使用して宣言または割り当てた場合と同じです。
現在のスコープで既に宣言されている場合(たとえば、グローバルスコープのときに環境からスカラー変数としてインポートされたため)、_declare -a a
_はconvertを試みます配列。
以前はスカラーだった場合は、_([0]=value-of-the-variable)
_配列になります。すでに配列だった場合はそのままにしておきます。連想配列の場合、_cannot convert associative to indexed array
_エラーで失敗します。
_declare a
_は配列またはハッシュをスカラーに変換しないことに注意してください。とにかくbash
はハッシュ/配列をスカラーに変換できません。 _declare +aA a
_を使用して、スカラーを強制できます(変数が以前に現在のスコープのハッシュ/配列であった場合、エラーで失敗します)。
あなたの場合、変数はおそらく現在のスコープでまだ宣言されていなかったため、宣言されたが割り当てられなかったため、_set -u
_で展開しようとすると失敗する理由がわかります。
変数の2つのdeclaredとassigned/setの状態の違いは、bash
に固有のものではありません。 POSIX sh
では、変数をexport
にするか、値を指定せずにreadonly
にすることもできます。
_$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set
_
unset
は、変数を設定解除および宣言解除することに注意してください。 bash
、mksh
およびyash
では、外部スコープから変数を復元できます。
zsh
では、sh
エミュレーションを除き、変数でtypeset
を使用すると、変数がまだ設定されていないか、設定されているが別の型からの場合は、宣言して空の値に設定します(スカラーvs配列vs連想配列)。