![Shebang은 `//`로 시작하나요?](https://linux55.com/image/57657/Shebang%EC%9D%80%20%60%2F%2F%60%EB%A1%9C%20%EC%8B%9C%EC%9E%91%ED%95%98%EB%82%98%EC%9A%94%3F.png)
다음 스크립트( )가 헷갈립니다 hello.go
.
//usr/bin/env go run $0 $@ ; exit
package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
}
실행될 준비가 되었습니다. (MacOS X 10.9.5)
$ chmod +x hello.go
$ ./hello.go
hello, world
로 시작하는 셔뱅에 대해 들어본 적이 없습니다 //
. 스크립트 상단에 빈 줄을 삽입해도 여전히 작동합니다. 이 스크립트가 작동하는 이유는 무엇입니까?
답변1
그것은 shebang이 아니며 단지 기본 쉘에서 실행되는 스크립트일 뿐입니다. 쉘은 첫 번째 줄을 실행합니다
//usr/bin/env go run $0 $@ ; exit
이로 인해 go
파일 이름으로 호출이 이루어지므로 결과적으로 파일이 go 스크립트로 실행된 다음 파일의 나머지 부분을 보지 않고 쉘이 종료됩니다.
//
그런데 왜 정당 /
하거나 적절한 shebang 으로 시작합니까 #!
?
이는 파일이 유효한 go 스크립트여야 하기 때문입니다. 그렇지 않으면 go에서 오류가 발생합니다. Go에서 이러한 문자는 //
주석을 나타내므로 go는 첫 번째 줄을 주석으로 처리하고 이를 해석하려고 시도하지 않습니다. 그러나 이 문자는 #
주석을 나타내지 않으므로 일반 shebang에서는 go가 파일을 해석할 때 오류가 발생합니다.
이 구문을 사용하는 이유는 단지 서로 밟지 않고 쉘 스크립트와 go 스크립트인 파일을 빌드하기 위한 것입니다.
답변2
실행 파일은 기본적으로 /bin/sh 스크립트로 간주되기 때문에 실행됩니다. 즉, 특정 쉘을 지정하지 않으면 #!/bin/sh가 됩니다.
//는 경로에서 무시됩니다. 단일 "/"로 처리할 수 있습니다.
따라서 자신이 쉘 스크립트의 첫 번째 줄을 갖고 있다고 생각할 수 있습니다.
/usr/bin/env go run $0 $@ ; exit
이 줄은 무엇을 합니까? "go run $0 $@" 매개변수를 사용하여 "env"를 실행합니다. 여기서 "go"는 명령이고 "run $0 $@"은 매개변수이며 스크립트를 종료합니다. $0은 스크립트 이름입니다. $@는 원래 스크립트 매개변수입니다. 따라서 이 줄은 go를 실행하여 인수와 함께 이 스크립트를 실행합니다.
주석에서 지적했듯이 매우 흥미로운 세부 사항이 있으며 두 개의 슬래시가 구현 정의되어 있으며 스크립트가 세 개 이상의 슬래시를 지정하면 스크립트가 POSIX에 맞게 됩니다. 인용하다http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html경로에서 슬래시를 처리하는 방법에 대한 세부정보입니다.
또한 $@ 스크립트에 또 다른 버그가 있다는 점에 유의하십시오. "$@"을 사용하는 것이 옳습니다. 그렇지 않으면 매개변수에 공백이 포함되어 있으면 여러 매개변수로 분할되기 때문입니다. 예를 들어 "$@"를 사용하지 않고는 공백이 포함된 파일 이름을 전달할 수 없습니다.
이 특정 스크립트는 분명히 "//"가 "/"와 같다는 생각에 의존하고 있습니다.
답변3
이는 C++(또는 C가 주석을 허용하는 경우 // C)에서 작동합니다.
//usr/bin/env sh -c 'p=$(expr '"_$0"' : "_\(.*\)\.[^.]*"); make $p > /dev/null && $p'; exit