Shebang 以 `//` 開頭?

Shebang 以 `//` 開頭?

我對以下腳本感到困惑(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 //。當我在腳本頂部插入空白行時它仍然有效。為什麼這個腳本有效?

答案1

它不是一個 shebang,它只是一個由預設 shell 運行的腳本。 shell執行第一行

//usr/bin/env go run $0 $@ ; exit 

這會導致go使用該檔案的名稱進行調用,因此結果是該檔案作為 go 腳本運行,然後 shell 退出而不查看檔案的其餘部分。

//但為什麼要從 just/或適當的 shebang開始呢#!

這是因為該檔案需要是有效的 go 腳本,否則 go 會抱怨。在 go 中,這些字元//表示註釋,因此 go 將第一行視為註釋,並且不會嘗試解釋它。然而,該字元#並不表示註釋,因此當 go 解釋檔案時,普通的 shebang 會導致錯誤。

這種語法的原因只是為了建構一個既是 shell 腳本又是 go 腳本的文件,而不需要互相踩踏。

答案2

它運行是因為預設情況下可執行檔被假定為 /bin/sh 腳本。即,如果您沒有指定任何特定的 shell - 它就是#!/bin/sh。

// 在路徑中被忽略 - 您可以將其視為單一“/”。

所以你可以認為你有第一行的 shell 腳本:

/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

相關內容