데비안 7에는 다음 쉘 스크립트가 있습니다.
#!/bin/sh
case "$IFACE" in
lo)
# The loopback interface does not count.
# only run when some other interface comes up
exit 0
;;
*)
;;
esac
(
flock -e 200
FLAGFILE=/var/run/cyvo-auto-started
if [ -e $FLAGFILE ]; then
exit 0
else
touch $FLAGFILE
fi
# Launch CyVo without the lock and as cyvo user
flock -u 200
sudo -u cyvo /usr/local/bin/cyvo-launch.sh
) 200>/var/lock/cyvo-autostart-lock # word unexpected here? (line 29)
그것이 나에게주는 오류는 다음과 같습니다
./cyvo: 29: ./cyvo: Syntax error: word unexpected
이것은 제안된 구문이기 때문에 정말 혼란스럽습니다.그룹주문하다. /var/lock/cyvo-autostart-lock
를 가리키는 파일 설명자 200을 전달합니다 ()
.
내가 뭘 잘못했나요?
답변1
쉘 스크립트에서 이식 가능하게 사용할 수 있는 유일한 파일 설명자 번호는 0부터 9까지(즉, 단일 숫자)입니다. 인용하다POSIX:
열린 파일은 0부터 시작하는 십진수로 표시됩니다. 가능한 최대 값은 구현에 따라 정의됩니다. 그러나 모든 구현은 애플리케이션 사용을 위해 최소 0~9(포함)를 지원해야 합니다. 이 숫자를 "파일 설명자"라고 합니다. (…) 파일 설명자 번호를 지정하기 위해 리디렉션 연산자 앞에 하나 이상의 숫자(<공백> 문자는 허용되지 않음)가 올 수 있습니다.
이것문법분명히 리디렉션 연산자 앞에 여러 개의 숫자가 있을 수 있습니다. 그러나 대부분의 쉘은 연산자 앞의 숫자가 단일 숫자로 구성된 경우 파일 설명자로만 구문 분석합니다. 예를 들어 POSIX 사양에 따르면 echo 10>a
파일 디스크립터 10을 리다이렉션하여 a
빈 파일을 생성해야 하며, 그렇지 않으면 쉘이 파일 디스크립터 번호로 10을 지원하지 않기 때문에 오류가 발생한다. 이 오류는 프로세스에서 열린 파일 수 제한을 초과하는 파일 설명자 수로 인해 발생할 수도 있습니다.
그러나 실제로 대부분의 쉘은 이를 echo 10 >a
write 10
in 으로 구문 분석합니다 a
. ATT ksh93 및 posh도 dash, mksh 및 zsh와 마찬가지로 규격을 준수하지 않습니다.
$ ksh -c 'echo 10>a; wc -c a'
3 a
$ posh -c 'echo 10>a; wc -c a'
3 a
Linux에서는 POSIX 호환 bash, yash 및 BusyBox의 ash만 찾을 수 있었습니다.
$ bash -c 'echo 10>a; wc -c a'
0 a
마찬가지로 (…) 200>somefile
리디렉션으로 구문 분석해야 하며 쉘이 이러한 높은 파일 설명자를 지원하는지 여부에 따라 작동할 수도 있고 작동하지 않을 수도 있습니다. 그러나 대부분의 쉘은 200
이 부분을 파일 설명자 번호가 아닌 일반 토큰으로 구문 분석하기 때문에 구문 오류를 보고합니다 .
관련 참고 사항에서 echo 01>&1
빈 줄은 01
파일 설명자 번호로 구문 분석되어야 하기 때문에 인쇄되어야 하지만 다시 bash 및 BusyBox ash만 이를 수행할 수 있습니다.
따라서 실제로는한 자리 숫자의 파일 설명자만 사용할 수 있습니다.쉘 스크립트에서. 설명자 0, 1, 2는 표준 의미를 가지며 설명자 3-9는 자유롭게 사용할 수 있습니다. 쉘은 내부 목적으로 fd 3–9를 사용하지 않습니다. 어떤 파일 설명자를 선택하든 쉘이 시작될 때 파일 설명자가 이미 열려 있을 수 있지만 이는 중요하지 않습니다. 스크립트 내의 모든 파일 설명자 재할당은 스크립트 내에 유지되며 스크립트의 상위 프로세스에 영향을 주지 않습니다.
답변2
다시 생각해 보면 내 원래 답변(원래 허용된 답변이었기 때문에 아래에 복사함)보다 더 간단한 접근 방식은 파일 설명자를 200
< 9에서 변경하는 것일 수 있습니다. 예를 들어 5. 따라서 200
스크립트의 세 인스턴스를 모두 다음으로 변경합니다 5
.
#!/bin/sh
case "$IFACE" in
lo)
# The loopback interface does not count.
# only run when some other interface comes up
exit 0
;;
*)
;;
esac
(
flock -e 5
FLAGFILE=/var/run/cyvo-auto-started
if [ -e $FLAGFILE ]; then
exit 0
else
touch $FLAGFILE
fi
# Launch CyVo without the lock and as cyvo user
flock -u 5
sudo -u cyvo /usr/local/bin/cyvo-launch.sh
) 5>/var/lock/cyvo-autostart-lock
원래 답변:
@GlennJackman이 제안한 대로 sh
파일 설명자 >9를 처리할 수 없거나 스크립트가 작동하지 않는 다른 특징이 있기 때문입니다 sh
( dash
데비안 기반 배포판). 사용해 봤는데 bash
효과가 좋았으니 그냥 사용해 보세요 bash
. 첫 번째 줄을 다음으로 변경하십시오.
#!/bin/sh
도착하다
#!/bin/bash
그러면 스크립트가 예상대로 작동해야 합니다.