最近あなたを見つけました。Bash配列に空の文字列を渡すことはできません。。空の文字列値を配列に挿入しようとしているので、これは面倒です。
しかし、Bash完了変数COMP_WORDSにNULL値を含めることができることを確認しました。
デバッグオプションを有効にしてこれを説明するためにダミーコンプリートスクリプトを作成しました。
1 #!/bin/bash
2 _comp() {
3 set -xv
4 for i in ${!COMP_WORDS[@]}; do
5 echo "<${COMP_WORDS[$i]}>"
6 done
7 set +xv
8 local cur=${COMP_WORDS[$COMP_CWORD]}
9
10 local arr=(apple banana mango pineapple)
11 COMPREPLY=()
12 COMPREPLY=($(compgen -W "${arr[*]}" -- $cur))
13
14 }
15
16 complete -F _comp dummy
ファイルを受け取り、次のように入力した場合:
dummy apple banana
その後、リンゴとバナナの間の中間空間(下の下線)にカーソルを戻すと...
dummy apple _ banana
次に、タブをクリックすると、4つの配列要素 'dummy' 'apple' 'banana'を表示する生成されたデバッグから、次のような出力が得られます。
for i in '${!COMP_WORDS[@]}'
+ echo '<dummy>'
<dummy>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<apple>'
<apple>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<>'
<>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<banana>'
<banana>
したがって、COMP_WORDS配列は明らかに何らかの空の文字列を格納できます。興味深いことに、これはいいえこれは、インデックスの代わりに配列要素にアクセスする通常のforループを使用している場合に発生します。つまり、デバッグセクションのforループを次のように変更すると...
for i in ${COMP_WORDS[@]}; do
echo "<$i>"
done
次に、 'dummy' 'apple' 'banana' 3つの配列要素のみを表示する次のデバッグ出力を取得します。
for i in '${COMP_WORDS[@]}'
+ echo '<dummy>'
<dummy>
+ for i in '${COMP_WORDS[@]}'
+ echo '<apple>'
<apple>
+ for i in '${COMP_WORDS[@]}'
+ echo '<banana>'
<banana>
- - を使って配列の長さをエコーしてみました。${#COMP_WORDS[@]}
この入力の場合、長さは4で示されます。したがって、これは明らかに4つの要素を含み、そのうちの1つは空の文字列です。
これは私にとって非常に奇妙な行動のようです。私の質問は2つあります。
通常の配列は明らかに空の文字列を格納できないが、COMP_WORDS配列が空の文字列を保存できるという説明は何ですか?
通常のforループを使用するときは空の文字列を見ることはできませんが、インデックスで配列要素にアクセスするときに表示されるのはなぜですか?
答え1
""
空の文字列とNULL文字を混同しているようです\0
。彼らは違う。配列と変数に空の文字列を使用できます。
$ a=(aa "" "b")
$ echo "${#a[@]}"
3
$ printf -- '- %s\n' "${a[@]}"
- aa
-
- b
$ for i in "${a[@]}"; do
> printf '%s\n' "$i"
> done
aa
b
一部条件式Bashでは、文字列が空であることをテストすることも許可されます。
-z 文字列
True if the length of string is zero.
-n 文字列文字列
True if the length of string is non-zero.
また、見ることができますいつ二重引用符が必要ですか?