2017-11-10 6 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} <& -'실수로 루프 내에서 같은 소스를 소비하는 것을 방지하기 때문에 exec를 수행하는 것이 옳습니다. – ephemient

관련 문제