#!/bin/bash
쉘 스크립트 파일의 첫 번째 shebang( ) 라인이 필요하며 이 라인이 없으면 파일이 정확하게 실행되지 않는다고 들었습니다 . 하지만 일부 스크립트를 테스트했습니다. 그 선 없이도 잘 작동합니다.
이 줄은 단지 주석인가요? bash는 다른 주석처럼 이 줄을 생략합니까? 아니면 bash가 그것을 해석할까요?
행이 해당 형식이어야 합니까? 아니면 단지 읽을 수 있는 유용한 댓글인가요? , 없이 다른 방식으로 표현한다면 어떨까요 !
?
답변1
커널 1 자체는 이를 알고 있습니다. shebang이 있어야 합니다. 그렇지 않으면 커널은 해당 파일을 실행 파일(스크립트)로 간주하지 않습니다.
Linux에서는 exec
시스템 호출(일명 execve
)이 다음 코드를 호출합니다. linux/fs/binfmt_script.c
.
static int load_script(struct linux_binprm *bprm)
{
[...]
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
return -ENOEXEC;
그러나 shebang이 없으면 쉘은 파일 자체를 실행하도록 선택할 수 있습니다. 바라보다 처음에 shebang 라인( )이 없을 때 어떤 쉘이 스크립트를 실행합니까?#!/path/to/shell
따라서 쉘 스크립트에서는 작동하는 것처럼 보이지만 의존해야 할 기능은 아닙니다.
하지만 쉘 스크립트가 bashism을 사용한다면 어떻게 될까요? #!/bin/bash
그런 다음 다른 쉘이 아닌 bash에서 실행되도록 해야 합니다 . 마찬가지로, 실행하려는 프로그램 자체가 쉘이 아닌 경우에도 실행됩니다. Perl이나 Python과 같이 완전히 다른 언어로 작성된 스크립트도 있습니다. shebang이 없으면 시스템은 이러한 작업에 어떤 통역사를 사용해야 할지 알 수 없습니다.
______________
1이것은 Unix의 기능입니다.방법Linux 이전에 참조하십시오.셰르본 역사.
답변2
이것셰르본스크립트를 실행할 때 어떤 프로그램을 호출할지 커널에 알려줍니다.곧장.
chmod +x myscript.sh
./myscript.sh
답변3
Shebang은 다음 조건 중 하나가 충족되는 경우에만 필요합니다.
귀하의 스크립트는 이식 불가능합니다. 즉, POSIX 표준에서 지원하지 않는 항목(예: bashisms, kshisms 등)을 사용하므로 어떤 인터프리터를 시작해야 하는지 지정해야 합니다. 여기에는 분명히 외국 스크립트 언어(csh, perl, python...)가 포함됩니다. 귀하의 질문은 에 관한 것이므로
#!/bin/bash
귀하에게 해당될 가능성이 높습니다.POSIX가 아닌 환경/모드에서 스크립트를 실행하고 있습니다.
그렇지 않으면 shebang이 필요하지 않으며 실제로 쉘 스크립트를 엄격하게 준수하는 경우에도 권장되지 않습니다. 그 이유는 대중적인 믿음에도 불구하고 /bin/sh
POSIX 셸의 기본 경로가 반드시 필요한 것은 아니기 때문입니다. 표준 쉘의 위치를 검색하는 유일한 지원 방법은 다음을 실행하는 것입니다.
PATH=`getconf PATH` command -v sh
POSIX 표준상태:
셸 명령 파일의 첫 번째 줄이 "#!" 문자로 시작하면 결과가 지정되지 않습니다.
답변4
보충제로프로스트슈츠의 답변, 일부 쉘은 해시뱅(shebang) 라인을 해석할 수 있습니다. Bash는 일반적으로 커널이 해시뱅 해석을 지원하지 않는 경우에만 이 기능을 활성화합니다.
그러나 shebangs 라인을 사용하려면 커널 소스 코드보다 Bash 소스 코드에서 사용하는 것이 더 쉬울 수 있습니다.
에서 bash/execute_cmd.c
:
#if !defined (HAVE_HASH_BANG_EXEC)
if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
return (execute_shell_script (sample, sample_len, command, args, env));
else
#endif
에서 bash/config.h
:
/* Define if the kernel can exec files beginning with #! */
#define HAVE_HASH_BANG_EXEC 1