이것이 나를 당황하게 만들었습니다!
우리는 몇 년 동안 아무런 불만 없이 실행되어 온 중요한 스크립트/프로세스를 호스팅하는 Solaris 시스템(버전: SunOS 5.8)을 보유하고 있습니다. 우리는 최근 좀 더 깊이 파고들어 내가 아는 한 작동하지 않아야 하지만 어떤 이유로 작동하는 테스트 조건을 발견했습니다.
$ sh
$ [ 90% -gt 95 ]; echo $?
1
$ [ 96% -gt 95 ]; echo $?
0
무엇? ! 이것은 우연처럼 보이지 않습니다.
$ [ 96% -lt 95 ]; echo $?
1
$ [ 96% -eq 96 ]; echo $?
0
%
이는 단지 다음 두 가지 중 하나 가 아닙니다 .
$ [ 96blah -eq 96 ]; echo $?
0
$ [ 1.2 -gt 1 ]; echo $?
1
이는 SunOS 5.8, 5.9 및 5.10의 경우인 것으로 보이지만 이전에는 이를 발견하지 못했습니다. 불행하게도 bash에 대한 심볼릭 링크가 없는지 쉽게 확인할 수 있는 다른 비Solaris 시스템이 없는 것 같습니다 /bin/sh
(덜 자유롭게 해석됩니다).
그렇다면 엉성한 코드(변수를 통과하고 아마도 눈치 채지 못할 수도 있음)를 제외하고 x%
왜 표준(아마도 Bourne?) 쉘은 이러한 테스트 매개 변수를 잘라서 정수로 처리합니까? 이것이 문서화 된 동작입니까? 아무것도 볼 수 없지만 man sh
아마도 뭔가를 놓친 것 같습니다.
참고: 이것은 실제로 다른 이상한 테스트 조건에서는 사소한 야유이지만 자체적으로 질문할 가치가 있을 수 있습니다.
답변1
주석을 예상한 행에 맞게 형식화할 수 없기 때문에 답변 양식을 사용하여 POSIX 쉘을 얻는 방법에 대한 주석을 설명하고 있습니다.
POSIX 쉘을 얻는 공식적인 방법은 다음과 같습니다.
1) unset PATH # if you run an older Bourne Shell
2a) PATH=`getconf PATH` # this is with the Bourne Shell
2b) PATH=$(command -p getconf PATH) # this is with a Korn shell
3) sh # This starts a POSIX shell
표준화를 위한 여러 시도가 있었지만 #!/path/to/shell
POSIX는 PATH를 처리하지 않아 해결책을 찾지 못했습니다.
답변2
이 질문에 대한 답변이 댓글에 있는 것 같습니다. Solaris sh
에는 몇 가지 특이한 점이 있습니다. 적어도 과거에는,POSIX 쉘도 아닙니다.. (Schily는 POSIX가 /bin/sh
POSIX일 필요는 없다는 점을 지적합니다 sh
. 즉, 완전히 이식 가능한 쉘 스크립트를 작성하려면 또 다른 과정을 거쳐야 한다는 의미입니다.)
이 질문에는 유용한 정보/링크가 있을 수 있습니다.https://superuser.com/questions/125728/what-is-the-difference-Between-bash-and-sh
Schily의 답변은 표준이 쓰레기를 뒤따르는 숫자에 어떤 일이 발생하는지 지정하지 않으므로 스크립트가 효과적으로 정의되지 않은 동작을 가지며 Solaris의 동작에 의존한다는 점을 지적합니다 sh
. 따라서 휴대성이 없습니다.
bash
이와 같은 점이 /bin/sh
Solaris 시스템에서 이를 사용하는 것이 권장되지 않는 주된 이유입니다. 일부 GNU/Linux 배포판에서는 dash
for 를 사용 /bin/sh
하고 다른 배포판에서는 bash
.
내가 설치한 3개의 쉘에서 코드를 테스트했습니다.
bash 4.3-11ubuntu2
$ [ 96blah -eq 96 ]; echo $?
bash: [: 96blah: integer expression expected
2
dash 0.5.7-4ubuntu1
$ [ 96blah -eq 96 ]; echo $?
dash: 1: [: Illegal number: 96blah
2
busybox sh 1.22.0-9ubuntu1
$ [ 96blah -eq 96 ]; echo $?
sh: 96blah: bad number
2
답변3
표준에는 테스트 연산자가 -gt
피연산자를 정수로 비교하는 것을 좋아한다고 명시되어 있지만 제공된 문자열이 정수가 아닐 때 어떤 일이 발생하는지에 대해서는 아무 것도 언급하지 않습니다. 따라서 관찰된 동작은 완전히 정확합니다. 참고: 역사적인 UNIX 동작과도 호환됩니다.
/bin/sh는 물론 bash에 연결되지 않습니다. 왜냐하면 bash는 표준을 준수하지 않고 많은 스크립트가 실패할 수 있기 때문입니다.
2010년에 Solaris 10이 개발되면서 /bin/sh는 ksh93으로 대체되었습니다. 비록 ksh가 bash보다 Bourne Shell과 더 잘 호환되지만 이로 인해 이전에는 Solaris가 다른 파일 시스템에서 / 및 /usr을 가질 수 없게 되었습니다. ksh93은 /usr에서 동적 라이브러리를 로드합니다.