Shell – Shebang starting with `//`

osxshebangshellshell-scriptslash

I'm confused about following script (hello.go).

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

package main
import "fmt"
func main() {
    fmt.Printf("hello, world\n")
}

It can execute. (on MacOS X 10.9.5)

$ chmod +x hello.go
$ ./hello.go
hello, world

I haven't heard about shebang starting with //. And it still working when I insert a blank line at the top of the script. Why does this script work?

Best Answer

It isn't a shebang, it is just a script that gets run by the default shell. The shell executes the first line

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

which causes go to be invoked with the name of this file, so the result is that this file is run as a go script and then the shell exits without looking at the rest of the file.

But why start with // instead of just / or a proper shebang #! ?

This is because the file need to be a valid go script, or go will complain. In go, the characters // denote a comment, so go sees the first line as a comment and does not attempt to interpret it. The character # however, does not denote a comment, so a normal shebang would result in an error when go interprets the file.

This reason for the syntax is just to build a file that is both a shell script and a go script without one stepping on the other.

Related Question