입력을 Bash while 루프로 파이프하고 루프가 끝난 후 변수를 보존하는 방법


87

Bash는 다음을 사용할 수 있습니다. cat <(echo "$FILECONTENT")

Bash는 또한 다음을 사용할 수 있습니다. while read i; do echo $i; done </etc/passwd

이전 두 가지를 결합하려면 다음을 사용할 수 있습니다. echo $FILECONTENT | while read i; do echo $i; done

마지막 문제는 하위 셸을 생성하고 while 루프가 종료 된 후 변수에 i더 이상 액세스 할 수 없다는 것입니다.

내 질문은 :

이와 같은 것을 달성하는 방법 : while read i; do echo $i; done <(echo "$FILECONTENT")또는 다른 말로 : iwhile 루프에서 살아남는 것을 어떻게 확신 할 수 있습니까?

while 문을에 묶는 것을 알고 {}있지만 이것은 문제를 해결하지 못합니다 (함수에서 while 루프를 사용하고 i변수를 반환한다고 상상해보십시오 )



관련 : stackoverflow.com/questions/37229058/… . 아래에 언급 된 프로세스 대체 lastpipe와 그 장단점 을 포함한 모든 옵션을 설명합니다 .
ivan_pozdeev

답변:


115

프로세스 대체에 대한 올바른 표기 는 다음과 같습니다.

while read i; do echo $i; done < <(echo "$FILECONTENT")

i루프 에 할당 된 마지막 값은 루프가 종료 될 때 사용할 수 있습니다. 대안은 다음과 같습니다.

echo $FILECONTENT | 
{
while read i; do echo $i; done
...do other things using $i here...
}

중괄호는 I / O 그룹화 작업이며 자체적으로 하위 쉘을 생성하지 않습니다. 이러한 맥락에서, 그들은 파이프 라인의 일부이며, 따라서 서브 쉘로 실행되지만,이 때문에이다 |는 없습니다 { ... }. 질문에서 이것을 언급합니다. AFAIK, 함수 내부에서 리턴 할 수 있습니다.


Bash는 또한 shopt내장 기능을 제공 하며 여러 옵션 중 하나는 다음과 같습니다.

lastpipe

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

따라서 스크립트에서 다음과 같은 것을 사용 sum하면 루프 이후에 modfied를 사용할 수 있습니다.

FILECONTENT="12 Name
13 Number
14 Information"
shopt -s lastpipe   # Comment this out to see the alternative behaviour
sum=0
echo "$FILECONTENT" |
while read number name; do ((sum+=$number)); done
echo $sum

명령 줄에서이 작업을 수행하면 일반적으로 '작업 제어가 활성화되지 않음'(즉, 명령 줄에서 작업 제어가 활성화 됨)이라는 오류가 발생합니다. 스크립트를 사용하지 않고 테스트하지 못했습니다.

또한 Gareth Rees답변 에서 언급했듯이 때때로 here 문자열을 사용할 수 있습니다 .

while read i; do echo $i; done <<< "$FILECONTENT"

이것은 필요하지 않습니다 shopt; 당신은 그것을 사용하여 프로세스를 저장할 수 있습니다.


내 무지를 용서하십시오. 나는 이것이 올바른 해결책이라는 것을 알고 있으며 대답으로 표시하여 나를 위해 일했습니다. 하지만 이제 내가 실행했을 때 while read i; do echo $i; done < <(cat /etc/passwd); echo $i마지막 줄을 두 번 반환하지 않았습니다. 내가 뭘 잘못하고 있니?
Wakan Tanka

@WakanTanka : 조금 실험을 해봐야했는데 ... 대답은 실패한 읽기 i가 빈 상태로 재설정 되어 루프 이후의 에코가 빈 줄을 에코한다는 것입니다.
Jonathan Leffler 2015

1
프로세스 대체 참조에 대한 명성. 나는 몰랐다.
Atcold

@Wakan Tanka : 당신과 같은 결과를 얻었 while read i; do x=$i; done < <(cat /etc/passwd); echo i=$i; echo x=$x습니다.
yurenchen

당신은 생명의 은인입니다! 유사한 솔루션을 몇 시간 동안 찾고있었습니다. 당신의 것이 일한 유일한 사람입니다.
Pat


0

이 함수는 jpg 파일 (bash)을 $ NUM 번 복제합니다.

function makeDups() {
NUM=$1
echo "Making $1 duplicates for $(ls -1 *.jpg|wc -l) files"
ls -1 *.jpg|sort|while read f
do
  COUNT=0
  while [ "$COUNT" -le "$NUM" ]
  do
    cp $f ${f//sm/${COUNT}sm}
    ((COUNT++))
  done
done
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.