POSIX 스펙 의 쉘 명령 언어 페이지에서 :
쉘 명령 파일의 첫 번째 행이 "#!"문자로 시작하면 결과가 지정되지 않습니다.
#!
POSIX 에서 동작을 지정하지 않은 이유는 무엇 입니까? 휴대 성이 뛰어나고 널리 사용되는 것은 불특정 한 행동을하게 될 것입니다.
exec()
함수를 구현하는 라이브러리에 의해 해석됩니다 . 따라서 여러 쉘을 검사한다고해서 실제로 얼마나 이식성이 좋은지 알 수 없습니다.
POSIX 스펙 의 쉘 명령 언어 페이지에서 :
쉘 명령 파일의 첫 번째 행이 "#!"문자로 시작하면 결과가 지정되지 않습니다.
#!
POSIX 에서 동작을 지정하지 않은 이유는 무엇 입니까? 휴대 성이 뛰어나고 널리 사용되는 것은 불특정 한 행동을하게 될 것입니다.
exec()
함수를 구현하는 라이브러리에 의해 해석됩니다 . 따라서 여러 쉘을 검사한다고해서 실제로 얼마나 이식성이 좋은지 알 수 없습니다.
답변:
나는 주로 다음과 같은 이유로 생각합니다.
동작은 구현마다 크게 다릅니다. 자세한 내용은 https://www.in-ulm.de/~mascheck/various/shebang/ 을 참조 하십시오.
같은 : 그것은 그러나 지금은 유닉스와 같은 구현 대부분의 최소 부분 집합 지정할 수 있습니다 #! *[^ ]+( +[^ ]+)?\n
첫 번째 단어는 네이티브 실행 파일의 절대 경로입니다 (그 하나 또는 두 단어의 휴대용 파일 이름 문자 세트로만 포함), 물건이 아닌를 실행 파일이 setuid / setgid 인 경우 너무 길고 동작이 지정되지 않고 인터프리터 경로 또는 스크립트 경로가 argv[0]
인터프리터에 전달되는지 여부가 구현에서 정의되었습니다 .
POSIX는 어쨌든 실행 파일의 경로를 지정하지 않습니다. 여러 시스템에서 유틸리티 - POSIX의 사전 한 /bin
/ /usr/bin
다른 곳 (Solaris 10의 같은 POSIX 유틸리티가 /bin/sh
에있는 Bourne 쉘 및 POSIX의 하나입니다 /usr/xpg4/bin
, 더 POSIX를 준수이지만, 경우 ksh93로 대체 솔라리스 11은 다른 대부분의 도구 /bin
는 여전히 고대 비 POSIX 도구 입니다). 일부 시스템은 POSIX 시스템이 아니지만 POSIX 모드 / 에뮬레이션이 있습니다. 모든 POSIX는 시스템이 POSIXly 동작하는 문서화 된 환경이 필요합니다.
예를 들어 Windows + Cygwin을 참조하십시오. 실제로 Windows + Cygwin을 사용하면 cygwin 응용 프로그램이 스크립트를 호출 할 때 기본 Windows 응용 프로그램이 아닌 she-bang이 사용됩니다.
따라서 POSIX가 shebang 메커니즘을 지정한 경우에도 POSIX sh
/ sed
/ awk
... 스크립트를 작성하는 데 사용할 수 없습니다 ( 옵션 종료를 허용하지 않으므로 신뢰할 수있는 sed
/ awk
스크립트 를 작성하는 데 shebang 메커니즘을 사용할 수 없습니다. 채점자).
이제 그것이 지정되지 않았다는 사실이 그것을 사용할 수 없다는 것을 의미하지는 않습니다 (물론, 그것이 #!
평범한 의견 일 것으로 예상 되고 첫 번째 줄을 시작해서는 안된다고 말합니다 ). POSIX는 당신이 할 경우 보증하지 않습니다.
POSIX의에서 스크립트, 휴가를 그녀 - 뱅 떨어져 쓰기 : 내 경험에 의하면, shebangs를 사용하여 당신에게 쉘 스크립트를 작성하는 POSIX의 방법을 사용하는 것보다 휴대 성을 더 보장을 제공 sh
구문과 희망은 어떤 스크립트는 POSIX의 준수를 호출 호출하는 sh
이다, 그것을 스크립트가 올바른 도구로 올바른 환경에서 호출되지만 그렇지 않은 경우에는 알 수 있습니다.
다음과 같은 작업을 수행해야 할 수도 있습니다.
#! /bin/sh -
if : ^ false; then : fine, POSIX system by default
else
# cover Solaris 10 or older. ": ^ false" returns false
# in the Bourne shell as ^ is an alias for | there for
# compatibility with the Thomson shell.
PATH=`getconf PATH`:$PATH; export PATH
exec /usr/xpg4/bin/sh - "$0" ${1+"$@"}
fi
# rest of script
Windows + Cygwin으로 이식하려면 파일 확장명 .bat
또는 .ps1
확장자를 사용 하여 파일 이름을 지정 하고 동일한 파일 에서 cygwin을 호출 cmd.exe
하거나 powershell.exe
호출하기 위해 유사한 트릭을 사용해야 할 수 있습니다 sh
.
sh
에서 실행 하는 해시 뱅 라인이 필요하지 않습니다 sh
.
execlp
또는 execvp
사용 된 경우에만 사실 입니까? 를 사용 execve
하면 ENOEXEC가 발생합니까?
모든 POSIX 호환 셸에서 동작이 일관된 것으로 보입니다. 여기 흔들 거실이 필요하지 않은 것 같습니다.
당신은 깊이보고하지 않습니다.
1980 년대에이 메커니즘은 사실상 표준화 되지 않았습니다 . Dennis Ritchie가이를 구현했지만 해당 구현은 우주의 AT & T 측면에서 대중에게 도달하지 못했습니다. BSD에서만 공개적으로 사용 가능하고 알려졌습니다. AT & T Unix에서 실행 가능한 쉘 스크립트를 사용할 수 없습니다. 따라서 표준화하는 것이 합리적이지 않았습니다. 사건의 상태는이 현대적인 도코로 대표됩니다.
BSD로 시작하는 파일은— Stephen Frede (1988). "시스템 X 릴리스 Y에서 프로그래밍". 호주 유닉스 시스템 사용자 그룹 뉴스 레터 . 권 9. 수 4. p. 111.#! interpreter
직접 실행할 수 있지만 SysV는 a.out 파일 만 직접 실행할 수 있습니다. 즉exec…()
, BSD 프로그램에서 루틴 중 하나의 인스턴스가 SysV에서 변경되어/bin/sh
해당 프로그램에 대한 인터프리터 (일반적으로 )를 대신 실행해야 할 수도 있습니다 .
여기서 중요한 점은 쉘을보고있는 반면 실행 가능한 쉘 스크립트의 존재는 실제로 exec…()
함수 의 문제입니다 . 쉘이하는 것은 오늘날에도 여전히 일부 쉘에서 발견되고 실행 가능한 스크립트 메커니즘 의 선구자 를 포함하고 있으며 일부 exec…p()
는 오해의 소지가 있습니다. 이와 관련하여 표준에서 다루어야 exec…()
할 것은 해석 된 스크립트가 작동하는 방식이며 POSIX가 처음 만들어 졌을 때 대상 운영 체제 스펙트럼의 주요 부분에서 처음에는 작동하지 않았습니다 .
부차적 인 질문은 왜 스크립트 통역사를위한 매직 넘버 메커니즘 이 우주의 AT & T 측에서 대중 에게 도달 하고 1990 년대 초에 System 5 Interface Definitionexec…()
에 문서화 되었기 때문에 이것이 표준화되지 않은 이유 입니다. :
인터프리터 파일은 다음 형식의 줄로 시작합니다—#! 경로명 [arg]여기서 pathname 은 인터프리터의 경로이고 arg 는 선택적 인수입니다. 당신은 때exec
통역 파일, 시스템은exec
지정된 통역이야.
exec
. 시스템 V 인터페이스 정의 . 1 권. 1991.
불행하게도, 행동은 오늘날 1980 년대와 같이 거의 광범위하게 존재하며 표준화해야 할 일반적인 행동은 없습니다. 일부 Unices (예 : HP-UX 및 FreeBSD)는 스크립트의 인터프리터로 스크립트를 지원하지 않습니다. 첫 줄이 공백으로 분리 된 하나, 둘 또는 많은 요소인지 여부는 MacOS (및 2005 이전의 FreeBSD 버전)와 다른 요소에 따라 다릅니다. 지원되는 최대 경로 길이가 다릅니다. ␀
POSIX 이식 가능한 파일 이름 문자 세트 이외의 문자는 선행 및 후행 공백과 같이 까다 롭습니다. 0, 1, 2 차 인수의 결과도 까다로워 시스템마다 상당한 차이가 있습니다. 현재 POSIX를 준수하지만 일부는 아닌 일부-유닉스 시스템은 여전히 그러한 메커니즘을 지원하지 않으며, 명령을 지정하면 더 이상 POSIX 규격이 아닌 시스템으로 변환됩니다.
script
. NetBSD 기타 정보 매뉴얼 . 2005-05-06.다른 답변 중 일부에서 언급했듯이 구현 방법이 다릅니다. 따라서 기존 스크립트와의 호환성 을 표준화 하고 보존 하기가 어렵습니다 . 최신 POSIX 시스템에서도 마찬가지입니다. 예를 들어, Linux는 공백으로 shebang을 완전히 토큰 화하지 않습니다. macOS에서는 스크립트 인터프리터가 다른 스크립트가 될 수 없습니다.