![종료 명령이 중첩된 while 루프를 종료하지 않는 이유는 무엇입니까? [복사]](https://linux55.com/image/84610/%EC%A2%85%EB%A3%8C%20%EB%AA%85%EB%A0%B9%EC%9D%B4%20%EC%A4%91%EC%B2%A9%EB%90%9C%20while%20%EB%A3%A8%ED%94%84%EB%A5%BC%20%EC%A2%85%EB%A3%8C%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%8A%94%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F%20%5B%EB%B3%B5%EC%82%AC%5D.png)
다음 스크립트가 있습니다. passwd의 첫 번째 문자를 모두 콘솔에 인쇄하지만 내 기대는 문자 하나만 가져온 다음 프로그램이 종료되는 것입니다.
#!/bin/sh
cat /etc/passwd |
while read -r line
do
echo ${line} |
grep -o . |
while read char
do
echo ${char}
exit 1
done
done
실제 출력:
r
b
d
a
(etc)
예상 출력:
r
답변1
파이프라인의 각 부분을 제외하고 Bourne과 같은 대부분의 셸은 하위 셸 zsh
에서 실행됩니다. or 를 ksh
사용하지 않는다고 가정 하면 스크립트에서 파이프라인의 마지막 부분이 서브셸에서 실행되므로 현재 셸 대신 해당 서브셸이 종료됩니다.zsh
ksh
exit
zsh
또는 에서 원하는 출력을 얻을 수 있습니다 ksh
.
그럼에도 불구하고 이 코드에는 많은 결함이 있습니다.
원하는 것이 파일의 첫 번째 문자를 얻는 것이라면 다음을 수행하십시오.
dd bs=1 count=1 if=/etc/passwd 2>/dev/null
또는 GNU를 사용하십시오 dd
:
dd status=none bs=1 count=1 if=/etc/passwd
ASCII 문자에서만 작동합니다. 멀티바이트 문자의 경우:
LC_ALL=en_US.utf8 awk '{print substr($0,1,1);exit}'
LC_ALL
텍스트가 속한 로캘로 변경합니다 .
답변2
파이프는 서브쉘을 생성합니다. 쉘 내장 명령은 exit
쉘을 종료합니다. 귀하의 경우 예기치 않은 동작이 발생합니다.
> exit | exit | echo wow
wow
한번 보시길 권합니다관로에 참여 man bash
. 또한 살펴보십시오 help exit
.