在while循环中使用Bash构建数组(不会持久化)?

时间:2017-11-10 05:03:01

标签: arrays bash loops

请考虑此示例,例如test.sh

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='()'" ?!

如果我取消注释for ((...行并对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")'

但是,如果我按发布的方式运行脚本,那么myarr会在while循环中构建,但一旦在外面,它就会为空:

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循环之后,或者更确切地说,在<select ng-model="col" material-select> <option ng-repeat="rc in cvsRCDetails">{{rc.RCL1}}</option> </select> 循环之后)为空 - 以及如何让它保留其值?

1 个答案:

答案 0 :(得分:3)

问题在于,由于使用了管道,您正在分支子shell并在子shell中填充数组中的条目。一旦你的循环结束,子shell终止并且那里的所有变化都会丢失。

您可以使用流程替换来避免这种情况:

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")