누군가 이 스크립트가 내가 기대하는 결과를 생성하지 않는 이유를 설명할 수 있습니까?
#!/bin/bash
#
var=0
ls -1 /tmp| while read file
do
echo $file
var=1
done
echo "var is $var"
파일 목록을 얻은 다음var is 0
var가 1이 아닌 이유는 무엇입니까? while 루프가 하위 쉘을 생성하기 때문입니까?
답변1
파이프는 그렇습니다. 예를 들어 $BASHPID
while 루프 내부와 외부에서 인쇄 하거나 다음을 수행하여 직접 확인할 수 있습니다 .
ls | while read file; do
sleep 100;
done
, 중지 C-Z
하고 나중에 터미널 세션에서 프로세스 트리를 확인 ps
하거나 봅니다.ps --forest
약간 다른 "파이프라인"을 통해 서브쉘을 방지할 수 있습니다.
var=0
while read file
do
echo $file; var=1
done < <(ls -1 /tmp/)
echo $var #=> 1
답변2
다른 좋은 답변에서는 이미 변수 값을 유지하지 않는 이유를 설명했습니다. 원한다면 이 주제에 대한 흥미로운 기사를 읽을 수 있습니다.파이프라인 내의 루프에 변수를 설정했습니다. 루프가 끝나면 왜 사라지나요? 아니면 파이프를 통해 데이터를 읽을 수 없는 이유는 무엇입니까?.
ls
나는 단지 구문 분석이 전혀 필요하지 않도록 파일을 반복하는 다른 방법을 보여주고 싶었습니다 .
for file in /tmp/*
do
echo "$file"
var=1
done
그게 다야! /tmp/*
Expand에게 디렉토리의 모든 내용을 제공하도록 요청하면 됩니다 /tmp
.
귀하의 스크립트는 실제 코드가 아닌 더미 코드인 것 같습니다. 그러나 특정 값이 포함되어 있는지 확인하고 싶다면 /tmp
다음과 같이 말할 수도 있습니다.
shopt -s nullglob
r=(/tmp/*)
그런 다음 배열의 요소 수를 계산합니다.
echo ${#r[@]}
이 패턴과 일치하는 항목이 없으면 리터럴 문자열로의 확장을 shopt -s nullblog
차단 하곤 했습니다./tmp/*
/tmp/*
답변3
while
아니요, 하지만 파이프는 그렇습니다. 따라서 while
예제는 서브셸에서 실행됩니다.
for
반복할 목록을 생성하는 명령이 루프가 아닌 하위 쉘에서 실행되는 루프를 사용하여 동일한 작업을 수행할 수 있는 경우가 많습니다 . 예를 들어:
for file in /tmp/*; do
echo "$file"
var=1
done