절대 경로가 있는 shebang이 기본값(POSIX)입니까?

절대 경로가 있는 shebang이 기본값(POSIX)입니까?

편집하다: 질문과 대답은 모두 정확하지만 여기서 묻는 질문은 그렇지 않습니다. 실제로 유지관리자는거부하다/usr/bin/env솔루션 으로 사용되는 대신 스크립트를 sh솔루션으로 다시 생성하면 다른 사용자의 설치가 중단됩니다. 따라서 env조회 용 POSIX는 아니지만 bash기본값은 표준으로 간주되기에 "충분"합니다.

nixos에 소프트웨어를 설치할 때 일부 오류가 발생합니다(특히하스켈 스택) 그리고 인터넷을 검색한 후 소프트웨어를 설치하는 특정 경로에 문제가 있는 사람들의 몇 가지 예를 발견했습니다.여기/usr/bin/env한 가지 예는 다른 사용자의 설치가 중단되었기 때문에 관리자가 bash를 찾는 동안 솔루션 수정 사항을 되돌린 경우였습니다 .

그렇다면 env설치에 대한 절대 경로(시스템 검색 경로에 의존함)를 알려주지 않고 shebang을 참조하는 것을 오류로 간주할 수 있습니까?

사용할 수 있다고 하네요

#!env bash

바꾸다

#!/usr/bin/env bash

설치된 절대 경로가 env모든 시스템의 기본 경로가 아닌 경우에는 어떻게 되나요?

답변1

POSIX는 shebang을 정확하게 해석하는 방법을 지정하지 않습니다. 에서 인용exec함수 계열'근본적인:

일반적인 역사적 구현은 다음과 같습니다.구현하다(),구현하다(), 구현하다(), 그리고구현하다()이 함수는 실행 파일(셸 스크립트 포함)로 인식되지 않는 모든 파일에 대해 [ENOEXEC] 오류를 반환합니다. 언제. . . 언제execlp()그리고execvp()함수가 이러한 파일을 발견하면 해당 파일이 쉘 스크립트라고 가정하고 해당 파일을 해석하는 것으로 알려진 명령 해석기를 호출합니다. POSIX.1-2008에서는 이제 이것이 필요합니다. 이러한 구현execvp()그리고execlp()[ENOEXEC] 오류는 명령 해석기의 실행 파일에 문제가 있는 드문 경우에만 발생합니다. 이러한 구현으로 인해 [ENOEXEC] 오류는 언급되지 않습니다.execlp() 또는execvp(), 구현에서는 여전히 이를 제공할 수 있습니다.

일부 역사적 구현이 쉘 스크립트를 처리하는 또 다른 방법은 파일의 처음 2바이트를 "#!" 문자열로 인식하고 파일의 첫 번째 줄의 나머지 부분을 실행할 명령 해석기의 이름으로 사용하는 것이었습니다.

표준 개발자가 지적한 혼란의 한 가지 잠재적인 원인은 프로세스 이미지 파일의 내용이 exec 기능 계열의 동작에 어떤 영향을 미치는가입니다. 다음은 취해진 조치에 대한 설명입니다.

  1. 프로세스 이미지 파일이 시스템에 유효한 실행 파일(적절한 권한이 있는 실행 가능하고 유효한 형식)인 경우 시스템은 파일을 실행합니다.

  2. 프로세스 이미지 파일에 적절한 권한이 있고 실행 가능하지만 해당 시스템에 유효하지 않은 형식(예: 다른 아키텍처에서 인식되는 바이너리)인 경우 오류입니다. 오류 번호[EINVAL]로 설정합니다(나중에 [EINVAL]에 대한 근거 참조).

  3. 프로세스 이미지 파일에 적절한 권한이 있지만 인식되지 않는 경우:

    1. 이게 전화였다면execlp()또는execvp(), 프로세스 이미지 파일이 쉘 스크립트라고 가정하고 명령 해석기를 호출합니다.

    2. 전화가 아니었다면execlp()또는execvp(), 그러면 오류가 발생하고오류 번호[ENOEXEC]로 설정합니다.

그리고 이전에는설명하다, 스크립트를 실행해야 한다고 나와 execlp있습니다 .execvpsh

Exec 함수 계열의 다른 구성원이 실패하여 설정된 경우오류 번호[ENOEXEC]에게,execlp()그리고execvp() 함수는 명령 해석기를 실행해야 하며, 명령이 실행되는 환경은 마치 호출된 프로세스와 같아야 합니다. 유틸리티 사용량구현하다()다음과 같이:

execl(<shell path>, arg0, file, arg1, ..., (char *)0);

그중<쉘 경로>는 지정되지 않은 경로 이름입니다. 유틸리티와 파일은 프로세스 이미지 파일입니다.execvp(), 어디 매개변수 0,아르기닌1등은 전달된 값에 해당합니다.execvp()존재하다매개변수 v[0],정액2, 등.

따라서 이러한 함수의 작동은 shebang의 작동과 동일합니다 sh file .... 스크립트가 POSIX 쉘에서 실행될 때 shebang의 효과는 지정되지 않습니다. 바라보다2.1. 쉘 소개:

  1. 쉘은 파일에서 입력을 읽습니다(참조:), 에서-씨옵션 또는체계()그리고팝펜()POSIX.1-2008 시스템 인터페이스 볼륨에 정의된 기능입니다. 쉘 명령 파일의 첫 번째 행이 #!" " 문자로 시작하면 결과가 지정되지 않습니다.

Zsh는 신경 쓰지 않지만 bash는 다음을 수행합니다.

$ cat foo.sh
#! env perl
echo $0
$ zsh -c ./foo.sh
Can't locate object method "echo" via package "./foo.sh" (perhaps you forgot to load "./foo.sh"?) at ./foo.sh line 2.
$ bash -c ./foo.sh
bash: ./foo.sh: env: bad interpreter: No such file or directory

PATHshebang에서 지정되지 않은 조회 에 의존하지 마십시오 . ( zsh -c ./foo.sh대신 실행하고 있다는 것을 알고 있지만 zsh foo.sh여기서 중요한 점은 명령을 실행할 때 셸이 수행하는 작업이 다를 수 있음을 보여주는 것입니다.)

답변2

env/usr/bin21세기에도 여전히 존재하는 거의 모든 유닉스 계열 시스템 에서 발견됩니다 . 내가 알고 있는 두 가지 예외는 SCO OpenServer(매우 오래된 서버에 대한 지원을 여전히 제공함)와 NextSTEP(아직 지원되는 하드웨어가 많지 않음)입니다. 이식성을 위해서는 를 사용하세요 #!/usr/bin/env. 다른 것은 이식성이 떨어집니다(단 #!/bin/sh, 자체적인 문제가 있으며 SCO에서 스크립트를 실행하려는 경우에만 유용합니다).

/usr/bin/envPOSIX 및 Single Unix 에서는 , 및 의 일부 항목을 /bin/sh제외하고 , 또는 또는 절대 경로를 정의하지 않습니다 . 공식 유닉스 표준은 아니지만 사실상의 표준이다.//tmp/dev/usr/bin/env

#!env전혀 쓸모가 없습니다. Shebang 조회는 변수를 사용하지 않고 PATH커널에 의해 수행됩니다. (PATH 조회를 수행하는 경우에는 #!bash그냥 작성하는 것이 좋습니다 )

#!/usr/bin/env bashbash 스크립트에는 전혀 문제가 없습니다. #!/bin/bash관리자의 거부에 대해 질문하고 있습니다.요청에 분노그리고는 별로 심각하게 받아들이지 않습니다.Bash 대신 표준 sh를 사용하도록 변경휴대성이 더 좋지만분명히 그건 효과가 없지(스크립트에는 비표준 구문이 하나 더 남아 있을 수 있습니다.) 다른 셸에서 작동하도록 스크립트를 변환할 수 없는 경우에도 스크립트를 대신 사용하도록 변경해야 #!/usr/bin/env bash합니다 #!/bin/bash.

관련 정보