스크립트 ( 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
으로 시작하는 shebang에 대해들은 적이 없습니다 //
. 그리고 스크립트 상단에 빈 줄을 삽입해도 여전히 작동합니다. 이 스크립트는 왜 작동합니까?
답변
그것은 shebang이 아니며 기본 쉘에 의해 실행되는 스크립트 일뿐입니다. 쉘은 첫 번째 줄을 실행
//usr/bin/env go run $0 $@ ; exit
이는 원인 go
이 파일의 이름으로 호출 할, 그래서 결과는이 파일이 파일의 나머지 부분을 보지 않고 다음 쉘 종료 갈 스크립트로 실행된다는 점이다.
그러나 왜 //
그냥 /
또는 적절한 shebang 대신 시작 #!
합니까?
파일이 유효한 go 스크립트 여야하거나 go가 불평하기 때문입니다. go에서 문자 //
는 주석을 나타내므로 go는 첫 번째 행을 주석으로보고 해석하지 않습니다. 그러나 문자 #
는 주석을 나타내지 않으므로 일반 shebang은 파일을 해석 할 때 오류가 발생합니다.
이 구문의 이유는 쉘 스크립트와 go 스크립트 인 파일을 빌드하는 것입니다.
답변
기본적으로 실행 파일은 / bin / sh 스크립트로 가정되기 때문에 실행됩니다. 즉, 특정 쉘을 지정하지 않은 경우 #! / bin / sh입니다.
//는 경로에서 무시됩니다. 단일 ‘/’로 간주 할 수 있습니다.
따라서 첫 줄에 쉘 스크립트가 있다고 생각할 수 있습니다.
/usr/bin/env go run $0 $@ ; exit
이 라인은 무엇을합니까? paramenters ‘go run $ 0 $ @’와 함께 ‘env’를 실행합니다. ‘go’는 명령이고 ‘run $ 0 $ @’은 인수이며 스크립트를 종료합니다. 이 스크립트 이름은 $ 0입니다. $ @는 원래 스크립트 인수입니다. 이 줄은이 스크립트를 실행합니다.
주석에서 알 수 있듯이 두 개의 슬래시가 구현 정의되어 있으며이 스크립트가 세 개 이상의 슬래시를 지정하면 POSIX로 수정됩니다. 경로에서 슬래시를 처리하는 방법에 대한 자세한 내용은 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html 을 참조하십시오 .
스크립트에서 $ @에 또 다른 실수가 있습니다. 그렇지 않으면 매개 변수에 공백이 있으면 많은 매개 변수로 분할되므로 “$ @”를 대신 사용하는 것이 좋습니다. 예를 들어 “$ @”를 사용하지 않으면 파일 이름을 공백으로 전달할 수 없습니다
이 특정 스크립트는 분명히 ‘//’가 ‘/’와 동일하다는 생각에 의존합니다.
답변
이것은 C ++에서 작동하며 C가 주석을 허용하는 경우 C입니다.
//usr/bin/env sh -c 'p=$(expr '"_$0"' : "_\(.*\)\.[^.]*"); make $p > /dev/null && $p'; exit