2017-11-10 3 views
1

は、言う、test.shをこの例を考えてみましょう:私はfor ((...行のコメントを解除した場合whileループ中のBashビルド配列(持続しない)?

cat > test.txt <<'EOF' 
test 1 
test 2 
test 3 
EOF 

declare -a myarr 
declare -p myarr # "declare: myarr: not found" 
myarr=() 
declare -p myarr # "declare -a myarr='()'" 
#for ((i=1; i<=3; i++)); do # ok 
sed -n 's!test!TEST!p' test.txt | while read i; do # not preserved ?! 
    myarr=("${myarr[@]}" "pass $i") 
    declare -p myarr 
done 
declare -p myarr # "declare -a myarr='()'" ?! 

、およびsed -n ...行をコメントし、bash test.shの出力が期待通りである:

test.sh: line 8: declare: myarr: not found 
declare -a myarr='()' 
declare -a myarr='([0]="pass 1")' 
declare -a myarr='([0]="pass 1" [1]="pass 2")' 
declare -a myarr='([0]="pass 1" [1]="pass 2" [2]="pass 3")' 
declare -a myarr='([0]="pass 1" [1]="pass 2" [2]="pass 3")' 

しかし、私の場合投稿されたスクリプトを実行すると、myarrwhileループに組み込まれますが、一度外側になると空です。

test.sh: line 8: declare: myarr: not found 
declare -a myarr='()' 
declare -a myarr='([0]="pass TEST 1")' 
declare -a myarr='([0]="pass TEST 1" [1]="pass TEST 2")' 
declare -a myarr='([0]="pass TEST 1" [1]="pass TEST 2" [2]="pass TEST 3")' 
declare -a myarr='()' 

この場合、なぜmyarrが(なぜか、またはwhileループの後で)空白になっています。どうすればその値を保持できますか?

+0

これは[BashFAQ#24](http://mywiki.wooledge.org/BashFAQ

あなたはこれを回避するために、プロセス置換を使用することができます/ 024)。 –

答えて

3

問題は、パイプラインを使用しているため、サブシェルをフォークし、サブシェル内の配列にエントリを設定することです。ループが終了すると、サブシェルが終了し、すべての変更がそこで失われます。

myarr=() 

while IFS= read -r line; do 
    myarr+=("pass $line") 
done < <(sed -n 's!test!TEST!p' test.txt) 

# examine the result 
declare -p myarr 

出力:

declare -a myarr=([0]="pass TEST 1" [1]="pass TEST 2" [2]="pass TEST 3") 
+1

多くのありがとう@anubhava - >それは確かに問題でした!乾杯! – sdaau

+0

私は 'exec {fd} <<(sed ...)のような他の形式の方が好きです。 -r -u $ fd行を読み込みます。行う ...;完了しました。 exec {fd} <& - 'はループ内で同じソースを誤って消費しないようにするためですが、これは正しい方法です。 – ephemient

関連する問題