
メニューなどのプログラムがあります。これには次の連想配列がありますconfig
。
declare -A config=( [h]="?" [c]="?" [x]="?" [l]="?" [t]="?" [n]="?" )
メインループでは、すべての値が設定されている場合にチェックされます。たとえば、次のようになります。
if [ "${config[h]}" == "Y" ] && [ "${config[c]}" == "Y" ] && [ "${config[l]}" == "Y" ] && [ "${config[x]}" == "Y" ] && [ "${config[t]}" == "Y" ] && [ "${config[n]}" == "Y" ];
今私はいつ終わる一度実行すると、配列の設定を解除して再宣言します。
unset config; declare -A config=( [h]="?" [c]="?" [x]="?" [l]="?" [t]="?" [n]="?" )
しかし、配列が正しく再宣言されていないようです。その理由は、私が設定したとき一つ[C]=Y
たとえば、if
文の値は渡されます。私はステートメントの本文がif
いくつかのテキストの色を変更するので、そうなることを確かに知っています。これは、残りのインデックスが実際に「?」に設定されていないためと思われるため、ステートメントはis beif
に単純化されます。私はステートメントの本文にエコーするときは間違いなく私は見ることができるだけだから、これを知っています。[ "${config[c]}" == "Y"]
true
$config[@]
if
一つ5の代わりに「Y」。配列を正しく再宣言するには?
編集する
関心をお寄せいただきありがとうございます。
一部のユーザー入力後、値はYに設定されます。この部分についてはかなり自分がいて質問では省略しました。すべて次の形式に従います。
read ch if [ $ch == "Hosts" ]; then while true; do nano listHosts echo -en "Commit this list of Hostnames? [Y|N to re-edit]: " read yn if [ $yn == "Y" ] || [ $yn == "y" ] || [ $yn == "yes" ]; then break elif [ $yn == "N" ] || [ $yn == "n" ] || [ $yn == "no" ]; then continue fi done config[h]="Y"
クサランダさんのコメントについて大小文字が正しいか確認してみましたが、常に小文字「c」ですね。また、そうです。私の言葉は
${config[@]}
…-p を宣言すると、いくつかの情報が提供されます。
declare -a config='([0]="Y")'
-pが小文字のaを使用したと言うのはなぜですか?呼び出しの順序は次のとおりです。
unset config
declare -A config=( [h]="?" [c]="?" [x]="?" [l]="?" [t]="?" [n]="?" )
read
その後、次のように$ ch = "Commands"を設定しました。
elif [ $ch == "Commands" ]; then
while true; do
nano iSet
echo -en "Commit this list of commands? [Y|N to re-edit]: "
read yn
if [ $yn == "Y" ] || [ $yn == "y" ] || [ $yn == "yes" ]; then
break
elif [ $yn == "N" ] || [ $yn == "n" ] || [ $yn == "no" ]; then
continue
fi
done
config[c]="Y"
declare -p config
Bodoが提案したように、より小さなスクリプトで再作成しようとしました。
dec() {
declare -A config=( [h]="?", [c]="?" )
}
test() {
declare -p config
if [ "${config[h]}" == "Y" ] && [ "${config[c]}" == "Y" ]; then
echo "Yup"
fi
}
dec
config[h]="Y"; config[c]="Y"
unset config
dec
config[h]="Y"
test
他のスクリプトと同様にif
true と確認されます。
declare -a config='([0]="Y")' Yup
答え1
関数では、配列をグローバル配列として宣言する必要がありますdeclare -g ...
。それ以外の場合、配列はローカル変数になります。機能上。バラよりhttps://unix.stackexchange.com/a/136721/330217
一部のデバッグ出力とともに、この修正されたスクリプトを参照してください。
#! /bin/bash
# set -x
dec() {
# declare -A config=( [h]="?", [c]="?" )
declare -gA config=( [h]="?" [c]="?" )
echo dec: ${config[*]}
}
test() {
declare -p config
if [ "${config[h]}" == "Y" ] && [ "${config[c]}" == "Y" ]; then
echo "Yup"
else
echo "No"
fi
echo test: ${config[*]}
}
dec
echo 1: ${config[*]}
config[h]="Y"; config[c]="Y"
echo 2: ${config[*]}
test
unset config
dec
echo 3: ${config[*]}
config[h]="Y"
echo 4: ${config[*]}
test
出力は次のとおりです
$ ./script
dec: ? ?
1: ? ?
2: Y Y
declare -A config=([c]="Y" [h]="Y" )
Yup
test: Y Y
dec: ? ?
3: ? ?
4: ? Y
declare -A config=([c]="?" [h]="Y" )
No
test: ? Y
その行のコメントを外し、変更された行にコメントを付けると、出力は次のようになります。
$ ./script
dec: ? ?,
1:
2: Y
declare -a config=([0]="Y")
Yup
test: Y
dec: ? ?,
3:
4: Y
declare -a config=([0]="Y")
Yup
test: Y
@ilkkachuのコメントからコピーされました:
もちろん、連想配列のローカル宣言が範囲外の後、割り当ては
config[h]="Y"
通常の配列を生成します。ここで、インデックスは算術コンテキストで解釈され、h
変数の値は(再帰的に)拡張されますh
。ケースを設定した後、ゼロと評価した結果が得られるため、空の文字列がconfig[0]
設定されます。そしてset -u
適用されないため、エラーメッセージもありません。
declare -a config=([0]="Y")
これは元のスクリプトの出力で見ることができます。