readarray
コマンドの奇妙な動作に固執しました。
man bash
の状態:
readarray Read lines from the standard input into the indexed array variable array
ただし、これらのスクリプトは機能しません(配列が空です):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
そしてこれらは機能します:
unset arr; readarray arr < /etc/passwd ; echo ${#arr[@]} unset arr; mkfifo /tmp/fifo; (echo a; echo b; echo c) > /tmp/fifo & mapfile arr < /tmp/fifo ; echo ${#arr[@]}
パイプの何が問題になっていますか?
回答
試してみてください:
unset arr printf %s\\n a b c | { readarray arr echo ${#arr[@]} }
うまくいくと思います、ただし、最後の{
シェル; }
コンテキストから|
pipeline there you “は変数値を失います。これは、|
パイプライン内の各|
個別の|
プロセスがで実行されるためです。 (
サブシェル)
。したがって、同じ理由で機能しません:
( arr=( a b c ) ) ; echo ${arr[@]}
…機能しません-変数値が異なる<に設定されました/ em>呼び出し元のシェルプロセスよりもシェルプロセス。
回答
コマンドは現在のシェルで実行され、パイプラインの代わりにプロセス置換を使用します:
readarray -t arr < <( echo a; echo b; echo c )
または(bash
4.2以降)lastpipe
シェルオプションを使用します:
shopt -s lastpipe ( echo a; echo b; echo c ) | readarray -t arr
コメント
回答
readarray
はstdinからも読み取ることができるため、次のようになります。
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
< <
2つの矢印があるとはどういう意味ですか?bash
のマニュアルページを参照してください。つまり、パイプラインをファイル記述子として扱うための'の構文です。< <(...)
は、<(...)
div内のコマンドの出力から入力(最初の<
)をリダイレクトすることを意味します>。同様に、> >(...)
は、標準出力を>(...)
内のパイプラインの標準入力に渡します。 'プロセス置換でリダイレクトを使用する必要は必ずしもありません。cat <( echo a b c )
も同様に機能します。readarray -t arr
を使用して行末を削除できます。man bash
から:-t Remove a trailing newline from each line read.
5.0.17で、これは'私には機能しません。 'も
BASHOPTS
をチェックしましたが、lastpipe
が含まれていますが、cat myfile.txt | readarray -t arr
は空のarr
を提供しますが、readarray -t arr < <(cat myfile.txt)
は正しく機能します。