입력을 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.