I like using shebangs to run my Perl scripts directly:
#!/usr/bin/env perl
What\'s the shebang for Go programs?
I prefer this:
///bin/true; exec /usr/bin/env go run "$0" "$@"
This has several advantages compared to the answer by هومن جاویدپور:
Uses exec
to replace the new shell process instead of launching a grandchild process. As a result, your Go program will be a direct child process. This is more efficient and it's also important for some advanced situations, such as debugging and monitoring.
Proper quoting of arguments. Spaces and special characters won't cause problems.
The leading ///
is more standards compliant than just //
. If you only use //
, you run the risk of bumping into implementation-defined behaviour. Here's a quote from http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html:
If a pathname begins with two successive
/
characters, the first component following the leading/
characters may be interpreted in an implementation-defined manner, although more than two leading/
characters shall be treated as a single/
character.
I have tested this answer with bash, dash, zsh, and ksh.
Example:
///bin/true; exec /usr/bin/env go run "$0" "$@"
package main
import "fmt"
func main() {
fmt.Println("你好!")
}
//usr/bin/go run $0 $@ ; exit
example:
//usr/bin/go run $0 $@ ; exit
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
go treat //
as a single line comment
and shell ignore extra /
Go programs are compiled to binaries; I don't think there is an option to run them directly from source.
This is similar to other compiled languages such as C++ or Java. Some languages (such as Haskell) offer both a fully compiled mode and a "script" mode which you can run directly from source with a shebang line.
There isn't one by default. There is a third-party tool called gorun that will allow you to do it, though. https://wiki.ubuntu.com/gorun
Unfortunately the compilers don't like the shebang line. You can't compile the same code you run with gorun.
So far, chaining sh and gorun has proven to be the most portable solution for me.
///bin/sh -c true && exec gorun "$0" "$@"
package main
import (
"fmt"
"log"
"os"
)
func main() {
fmt.Println("hello")
log.Printf("args: %v", os.Args)
// just to test exit code, would be 0x11
os.Exit(17)
}
OUTPUT:
00:~ $ chmod a+x test.go && ./test.go rawr
hello
2020/01/21 23:17:40 args: [./test.go rawr]
11:~ $
/// 2>/dev/null; gorun "$0" "$@" ; exit $?
Seems to me the best combination of the answers thus far. It uses gorun
so it caches the compilation step (which speeds up your scripts greatly), and works on macOS, too.
Install gorun
with:
go get github.com/erning/gorun