Bashマップファイルの配列数が異なります。

Bashマップファイルの配列数が異なります。

私は次のことをしました。

mapfile -t array < <(commands)

改行で区切られた出力を生成しますcommands

その後、結果に応じて配列に何もない場合は終了し、それ以外の場合は続行します。

[[ "${#array[@]}" -eq 0 ]] && exit

...

問題は、この条件が決して満たされないということです。commands何も返さないと、ゼロではなく${#array[@]}1を返すからです。

ただし、次のように配列を割り当てると、数が正確になります。

array=($(commands))

私のテスト:

$ declare -a array
$ array=($(echo))
$ echo ${#array[@]}
0
$ unset array
$ mapfile -t array < <(echo)
$ echo ${#array[@]}
1

なぜ?


array=($(commands))最初はこの形式を使用しましたが、shellcheck代わりにこの形式を使用することをお勧めしますmapfile

GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

ベストアンサー1

コマンドに何も印刷されない場合は、次の結果が表示されます。

$ mapfile -t array < <(printf ''); echo "num: ${#array[@]}"; declare -p array
num: 0
declare -a array=()

空白行を印刷すると、次のような結果が得られます。

$ mapfile -t array < <(echo); echo "num: ${#array[@]}"; declare -p array
num: 1
declare -a array=([0]="")

空の行は空の要素を生成します。これは非常に適切です。

プログラムでこのような空白行が生成され、これを防ぐことができない場合は、次を使用してgrepそれらを削除できます。または、単一の配列要素が空であることを確認してください。

空行を削除するには、次のコマンドを使用しますgrep

$ mapfile -t array < <(echo | grep .); echo "num: ${#array[@]}"; declare -p array
num: 0
declare -a array=()

空の要素があることを確認してください。

$ mapfile -t array < <(echo);
$ if [[ "${#array[@]}" = 0 || "${#array[@]}" = 1 && "${array[0]}" = "" ]]; then 
    echo "empty list or only one empty element"; 
 fi
empty list or only one empty element

存在する

array=($(commands))

コマンド置換の結果がトークン化され、末尾のスペースも削除されるために異なります。そして行を空白で割ります。 (コマンド置換自体も末尾の改行を削除しますが、ここでは重要ではありません。)

おすすめ記事