Shebang starting with `//`?

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.


It runs because by default executable file is assumed to be /bin/sh script. I.e. if you didn't specify any particular shell - it is #!/bin/sh.

The // is just ignored in paths - you can consider is at as single '/'.

So you can consider that you have shell script with first line:

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

What does this line do? It runs 'env' with paramenters 'go run $0 $@'. there 'go' is command and 'run $0 $@' are args and exits script afterwards. $0 is this script name. $@ are original script arguments. So this line runs go which runs this script with it's arguments

There are quite interesting details, as pointed in comments, that two slashes are implementation-defined, and this script would become POSIX-correct if it specify three or more slashes. Refer to http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html for details on how slashes should be handled in paths.

Note also that there is another mistake in script the $@ it's correct to use "$@" instead, because otherwise if any parameter contains spaces it will be split to many parameters. For example you can't pass file name with spaces if you not using the "$@"

This particular script obviously rely on the idea that '//' is equal to '/'