whileループの後に配列が空になるのはなぜですか? [コピー]

whileループの後に配列が空になるのはなぜですか? [コピー]

次の方法でbash-4.2で配列を初期化しようとしています。

ring=()
ls -las | tail -n +4 | while read line
> do
> ring+=("$line")
> echo ${ring[-1]}
> done
3924 -rw-r--r-- 1 username group 4015716 Mar 23 15:14 script.jar
4 -rw-r--r-- 1 username group 9 Feb 29 12:40 rec.lst
5541 -rw-r--r-- 1 username group 5674226917 Mar 28 15:25 debug.out
8 -rw-r--r-- 1 username group 6135 Mar 25 12:16 script.class
8 -rw-r--r-- 1 username group 6377 Mar 25 11:57 script.java
8 -rwxr-xr-x 1 username group 4930 Mar 8 15:21 script-0.0.0.sh
8 -rwxr-xr-x 1 username group 6361 Mar 28 15:27 script-0.0.1.sh
echo ${ring[0]}

echo "${ring[0]}"

echo "${ring[@]}"

何が間違っていて、ループが終了した後に空の配列が表示されるのですか?

ベストアンサー1

問題は、パイプ(command1 | command2 | command3 ...)でコマンドがサブシェルで実行されることです。変数はサブシェル間やサブシェルとメインシェル間で共有されません。 while ループ内のループは、ring基本シェルのループとは異なります。ring

この問題を克服する1つの方法は、プロセス置換を使用することです。

while read line;  do  ring+=("$line");  echo ${ring[-1]};  done < <(ls -las|tail -n +4) 

文法<(command)と呼ばれますプロセスの交換コマンドの出力を名前付きパイプにリダイレクトします。その後、<まるでファイルのように、おなじみのファイルにリダイレクトされます。を使用すると<サブシェルがないため、ringこの変数が設定されます。

ファイルの行から配列を埋めるシェルが組み込まれています。

mapfile -t ring < <(ls -las | tail -n +4)

おすすめ記事