루프에서 작동하는 bash 산술; var는 루프 후에 값이 없습니다.

루프에서 작동하는 bash 산술; var는 루프 후에 값이 없습니다.

루프 반복 횟수를 계산하기 위해 정수를 사용하려고 하는데 루프가 완료된 후 변수가 비어 있습니다. 단서를 찾았지만 운이 없습니다.

나는 이 코드를 가지고 있습니다 :

#!/bin/bash

declare -i count

echo entering loop

while read var
do
  (( count++ ))
  echo $count
done

echo exited loop
echo count is $count

대화형으로 실행하면 "c"를 입력한 후 Ctrl+D를 누르면 다음과 같은 결과가 나타납니다.

$ ./example
entering loop
a
1
b
2
c
3
exited loop
count is 3

하지만 루프에 입력을 공급하면 다음과 같습니다.

#!/bin/bash

declare -i count

echo entering loop

ls -la | while read var
do
  (( count++ ))
  # do something interesting here
  echo $count
done

echo exited loop
echo count is $count

...이 결과는 다음과 같습니다.

$ ./example
entering loop
1
2
3
4
5
exited loop
count is
$

루프를 종료한 후 "count is 5"가 나타나지 않는 이유는 무엇입니까?

답변1

while 루프에 값을 파이프하면 파이프의 명령이 서브셸에서 실행되고 while 루프가 끝나면 카운터 변수의 값이 손실됩니다.

다음을 사용하여 이 문제를 해결할 수 있습니다.프로세스 교체파이프 대신:

#!/bin/bash

declare -i count
while read var
do
  ((count++))
  echo "$count"
done < <(ls -la)
echo "count is $count"

또는 현재 셸 컨텍스트에서 파이프라인의 마지막 명령을 실행하는 lastpipe기능을 활성화할 수 있습니다.bash

https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html

lastpipe
설정되어 있고 작업 제어가 활성화되지 않은 경우 셸은 백그라운드에서 실행되지 않는 현재 셸 환경에서 파이프라인의 마지막 명령을 실행합니다.

#!/bin/bash

declare -i count
shopt -s lastpipe # enable lastpipe
ls -la | while read var
do
  ((count++))
  echo "$count"
done
shopt -u lastpipe # disable lastpipe
echo "count is $count"

관련된:

답변2

BASH 매뉴얼의 섹션 3.2.2를 참조하십시오.https://www.gnu.org/software/bash/manual/bash.html

각 파이프라인은 별도의 하위 셸에서 실행되므로 파이프라인 명령의 count 변수 업데이트는 범위를 벗어납니다.

그러나 shopt -s lastpipe스크립트 시작 부분의 기본 범위를 사용하여 최종 파이프라인 실행을 설정할 수 있습니다. 이렇게 하면 카운터 변수가 스크립트의 기본 셸과 동일한 범위로 업데이트되어 최종 카운터 값이 복원될 수 있습니다.

관련 정보