스크립트의 첫 번째 줄에는 어떤 언어가 표시됩니까? [복사]

스크립트의 첫 번째 줄에는 어떤 언어가 표시됩니까? [복사]

Bash 스크립트는 다음 줄로 시작합니다.

#!/bin/bash
# Rest of script below
...

in bash문자 #는 주석의 시작이지만 #!/bin/bash확실히 주석이 아니므로bash가 아니라 커널입니다.이 진술을 설명하십시오.

그렇다면 첫 번째 줄은 정확히 무엇입니까? 특정 언어인가요, 아니면 Linux 커널의 특별한 일회성 상황인가요? 스크립트를 작성할 때 사용할 수 있는 이 "언어"에 다른 명령이나 명령문이 있습니까?

답변1

그건셰르본. 파일 이름을 인수로 받아들이는 모든 프로그램을 여기에서 지정하여 스크립트의 파일 이름을 전달할 수 있습니다.

$ cat t.ex
#!/bin/cat
I have been cat!
$ ./t.ex
#!/bin/cat
I have been cat!

답변2

Ignacio가 말했듯이 이것은 shebang이라고 불리며 실제로 운영 체제의 프로그램 로더에 대한 약간의 마법입니다. 사용자가 프로그램을 실행하려고 하면 로더는 {something}에 대해 학습하기 위해 프로그램의 처음 2바이트를 읽습니다. 이 두 바이트가 # 및 !인 경우 커널은 바이트 3부터 첫 번째 개행 문자(많은 시스템에서 개행 문자)까지의 모든 내용을 읽습니다. 찾은 문자열을 경로 이름으로 사용한 다음, 경로 이름에서 무엇이든 실행할 수 있으면 그렇게 하고 첫 번째 프로그램 파일의 나머지 부분을 해당 실행 파일에 대한 입력으로 제공합니다.

더 완전한 설명을 원하는 사람들은 Google에서 "shebang 커널 마술"을 검색하고 해당 주제에 대한 Wikipedia 항목의 링크를 따라갈 수 있습니다.http://en.wikipedia.org/wiki/Shebang_(유닉스)

답변3

이것셰르본( #!)그게 바로 소위야매직넘버. #!2바이트 0x23과 0x21의 읽을 수 있는 형식입니다. C 함수에 대한 매뉴얼 페이지를 보면 execve()이러한 exec 함수 계열은 해당 바이트에서 얻는 내용을 얻고 존재할 때 다르게 동작합니다.

execve() 매뉴얼 페이지에서

DESCRIPTION
       execve()  executes the program pointed to by filename.  filename must be 
       either a binary executable, or a script starting with a line of the form:

           #! interpreter [optional-arg]

       For details of the latter case, see "Interpreter scripts" below.

       argv is an array of argument strings passed to the new program.  envp is 
       an array of strings, conventionally of the  form key=value,  which are 
       passed as environment to the new program.  Both argv and envp must be 
       terminated by a null pointer. The argument vector and environment can be 
       accessed by the called program's main function, when it is defined as:

           int main(int argc, char *argv[], char *envp[])

       execve() does not return on success, and the text, data, bss, and stack 
       of the calling process are overwritten by that of the program loaded.

       If the current program is being ptraced, a SIGTRAP is sent to it after a
       successful execve().

예리한 눈을 가진 사람은 shebang 형식에 매개변수가 2개만 필요하다는 것을 알 수 있습니다. 하나는 인터프리터이고 다른 하나는 입니다 [optional-arg]. 따라서 적어도 Linux에서는 1개 이상의 인수를 전달할 수 없습니다.

-f그래서 나는 그러한 명령이 효과가 없으며 무시될 것이라고 믿습니다.

#!/usr/bin/foo -i -f

그러나 인터프리터가 지원하는 경우 다음을 통해 이 제한을 어느 정도 우회할 수 있습니다.

#!/usr/bin/foo -if

관련 정보