모든 스크립트 파일이
#!/bin/sh
또는
#!/bin/csh
그게 필요합니까? 이것의 목적은 무엇입니까? 그리고 둘의 차이점은 무엇입니까?
답변:
이것은 다음과 같이 알려져 있습니다 Shebang
.
http://en.wikipedia.org/wiki/Shebang_(Unix)
#! interpreter [optional-arg]
shebang은 스크립트에 실행 권한이있는 경우에만 관련됩니다 (예 : chmod u + x script.sh).
쉘이 스크립트를 실행할 때 지정된 인터프리터를 사용합니다.
예:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
이 #!
줄은 커널 (특히 execve
시스템 호출 의 구현 )에이 프로그램이 해석 된 언어로 작성되었음을 알려줍니다 . 다음에 오는 절대 경로 이름은 인터프리터를 식별합니다. 기계어 코드로 컴파일 된 프로그램은 대부분의 최신 Unix에서 7f 45 4c 46
( ^?ELF) 다른 바이트 시퀀스로 시작하여 이를 식별합니다.
프로그램 자체가 스크립트 가 아닌 한 , 뒤에 원하는 프로그램 에 대한 절대 경로를 넣을 수 있습니다 . 커널은 다음 호출을 다시 작성합니다.#!
#!
./script arg1 arg2 arg3 ...
명령 줄이 실제로 있었던 것처럼 ./script
시작하는 곳 은#! /usr/bin/perl
/usr/bin/perl ./script arg1 arg2 arg3
또는 #! /bin/sh
이미 살펴본 것처럼를 사용하여에서 해석 할 스크립트를 작성할 수 있습니다 sh
.
이 #!
줄은 명령 줄 에서 스크립트 를 직접 호출하는 경우에만 처리됩니다 ./script
. 파일도 실행 가능해야합니다 ( chmod +x script
). 그렇게 sh ./script
하면 #!
라인이 필요하지 않으며 (존재하는 경우 무시 됨) 파일이 실행 가능하지 않아도됩니다. 포인트 기능의 그들이에 기록 된 어떤 언어 몰라도 해석 언어 프로그램 된 invoke 직접 당신을 허용하는 것입니다. (음주 grep '^#!' /usr/bin/*
- 당신은 수많은 재고 프로그램이이 기능을 사용하여 사실에 있음을 발견 할 것입니다.)
이 기능을 사용하기위한 몇 가지 규칙은 다음과 같습니다.
#!
맨 처음이해야 바이트 파일입니다. 특히 파일 은 ASCII 호환 인코딩 (예 : UTF-8은 작동하지만 UTF-16은 작동하지 않음) 이어야 하며 "바이트 순서 표시"로 시작 해서는 안됩니다. 그렇지 않으면 커널이이를 인식하지 못합니다. #!
스크립트.#!
는 절대 경로 여야합니다 (로 시작 /
). 공백, 탭 또는 개행 문자를 포함 할 수 없습니다.#!
와 사이에 공백을 두는 것은 좋은 스타일이지만 필수는 아닙니다 /
. 여기에 두 개 이상의 공간을 두지 마십시오.#!
줄 에 셸 변수를 넣을 수 없으며 확장되지 않습니다.#! /usr/bin/awk -f
) 때로는 유용합니다 ( #! /usr/bin/perl -Tw
). 불행히도 절대 경로 뒤에 두 개 이상의 인수를 넣을 수 없습니다 .#! /usr/bin/env interpreter
대신 을 사용하라고 말할 것입니다 #! /absolute/path/to/interpreter
. 이것은 거의 항상 실수입니다. 프로그램의 동작은 $PATH
스크립트를 호출하는 사용자 의 변수에 따라 달라집니다 . 그리고 모든 시스템이 env
애초에 그런 것은 아닙니다 .setuid
하거나 setgid
권한이없는 프로그램은 사용할 수 없습니다 #!
. 기계 코드로 컴파일해야합니다. (무엇인지 모르더라도 setuid
걱정하지 마십시오.)에 관해서 는 Nutrimat Advanced Tea Substitute 가 차에하는 것과 대략적으로 csh
관련이 있습니다. 대화식 사용 에 비해 많은 이점 이 있지만 (또는 그보다 최근의 구현 이 따라 잡았 지만 ) 스크립팅에 사용하는 것은 거의 항상 실수 입니다. 일반적으로 셸 스크립팅을 처음 사용하는 경우 무시하고 . 친척을 로그인 셸로 사용하는 경우 또는로 전환 하여 대화 형 명령 언어가 학습중인 스크립팅 언어와 동일하도록합니다.sh
sh
sh
tcsh
sh
csh
bash
zsh
#!
. 좋은 스타일인지에 대해서는 언급하지 않습니다. 해킹 의 장단점에 대한 토론은 이 질문 과 내 대답 을 참조하십시오 #!/usr/bin/env
.
#!/usr/bin/env
이 옳은 일이었던 상황에 직면 했지만 거의 항상 나쁜 생각이라고 생각합니다.
이것은 스크립트를 해석 / 실행하기 위해 사용하는 쉘 (명령 인터프리터)을 정의합니다. 각 셸은 사용자와 상호 작용하고 스크립트 (프로그램)를 실행하는 방식이 약간 다릅니다.
Unix 프롬프트에서 명령을 입력하면 쉘과 상호 작용하게됩니다.
예 #!/bin/csh
를 들어 C- 쉘, /bin/tcsh
t- 쉘, /bin/bash
bash 쉘 등을 나타냅니다 .
어떤 대화 형 셸을 사용하고 있는지 알 수 있습니다.
echo $SHELL
명령 또는 대안으로
env | grep -i shell
명령을 사용하여 명령 셸을 변경할 수 있습니다 chsh
.
각각은 약간 다른 명령 집합과 변수 할당 방법 및 자체 프로그래밍 구성 집합을 가지고 있습니다. 예를 들어 bash를 사용하는 if-else 문은 C- 셸에있는 문과 다르게 보입니다.
이 페이지 는 bash와 tcsh 명령 / 구문을 "번역"하므로 흥미로울 수 있습니다.
쉘 스크립트에서 지시문을 사용하면 다른 쉘을 사용하여 프로그램을 실행할 수 있습니다. 예를 들어 tcsh
셸을 대화식으로 사용하지만 종종 스크립트 파일에서 / bin / bash를 사용하여 bash 스크립트를 실행합니다.
곁에:
이 개념은 다른 스크립트에도 적용됩니다. 예를 들어 Python으로 프로그래밍하면
#!/usr/bin/python
Python 프로그램 맨 위에
#! $SHELL
? 이것이 Shebang에 올바른 쉘을 넣을까요?
!#/bin/bash
. 그것은 eg, 지시문 의 아름다움입니다 . 쉘 스크립트를 실행하기 위해 사용할 쉘을 시스템에 알려줍니다.
$SHELL
이 현재 실행중인 셸을 반드시 알려주 는 것은 아닙니다. 일반적으로 기본 셸을 알려줍니다 . tcsh 세트 $version
및 $tcsh
; bash 세트 $BASH_VERSION
. 모든 쉘이 반드시 유사한 메커니즘을 가지고있는 것은 아닙니다.
#!
줄은 스크립트 를 실행하는 사람이 사용하는 대화 형 셸이 아니라 스크립트 구문과 일치해야합니다 .
#!/bin/csh -f
; 는-f
소스하지 쉘을 알려주는 사용자.login
와.cshrc
빠른 스크립트 실행을하고 사용자의 설정에 대한 종속성을 피한다. (또는 더 좋은 방법은 csh 스크립트를 작성하지 않는 것-f
입니다 .) sh 또는 bash 스크립트 에는 사용하지 마십시오 . 같은 의미가 아닙니다.