"읽는 동안"이 터미널에서는 작동하지만 쉘 스크립트에서는 작동하지 않는 이유는 무엇입니까?

"읽는 동안"이 터미널에서는 작동하지만 쉘 스크립트에서는 작동하지 않는 이유는 무엇입니까?

루트 창의 제목을 설정하여 적용된 정보 텍스트로 WM 막대를 채울 때 이 흥미로운 문제에 직면했습니다.xsetroot -name "clever words"

이를 위해 터미널에서 운세를 인쇄하는 것이 효과적입니다.

fortune -s | while read -r; do xsetroot -name "$REPLY"; done

그러나 쉘 스크립트에서 실행하면 동일한 오류가 발생합니다.

#!/bin/sh
cat /tmp/afile | while read; do echo "$REPLY"; done

생산:

$ sh afilereader
afilereader: 2: 읽기: 인수 개수

물론 이는 부의 결과를 변수에 할당한 다음 해당 변수와 함께 xsetroot를 사용하여 해결할 수 있습니다. 하지만 난 아직도 이해하고 싶어이것은 스크립트에서 작동하지 않습니다.

파이프 양쪽의 각 명령이 자체 하위 쉘에서 실행된다는 것을 알고 있지만 해당 지역화된 변수가 while read 루프에 어떤 영향을 미치는지 확인할 수 없습니다. 아니면 루프 반복 사이에도 변수가 범위를 벗어나나요?

내가 놓친 게 무엇입니까?

고쳐 쓰다:내가 sh사용하는 링크는 POSIX와 호환되는 dash입니다. 더 존경받는 사람들을 활용하면 bash문제가 해결됩니다.

답변1

실행 중인 것으로 보이는 첫 번째 예 bash와 가리키는 내용의 두 번째 예 /bin/sh는 POSIX 셸이며 입력을 넣을 변수를 지정하는 인수를 전달해야 합니다. Shebang을 다음으로 변경하면 #!/bin/bash문제가 해결됩니다.

답변2

sh 구문에는 다음이 필요합니다.

IFS= read -r REPLY

일부 셸(예: ksh, bash 및 zsh)에서는 read변수 이름 없이 호출을 허용하지만 동작은 서로 다릅니다. 예를 들어 출력을 참조하세요.

printf 'te\ st\\\na ' | "$shell" -c 'read; printf "%s\n" "<$REPLY>"'

bash, zsh, pdksh 및 ksh93은 모두 다릅니다.

관련 정보