Skip to content

Instantly share code, notes, and snippets.

Last active October 8, 2022 17:23
Show Gist options
  • Save msoap/a9ee054f80a58b16867c to your computer and use it in GitHub Desktop.
Save msoap/a9ee054f80a58b16867c to your computer and use it in GitHub Desktop.
Run Go program as script
//usr/bin/env go run $0 "$@"; exit
package main
import (
func main() {
fmt.Println("Hello world!")
cwd, _ := os.Getwd()
fmt.Println("cwd:", cwd)
fmt.Println("args:", os.Args[1:])
Copy link

msoap commented Mar 13, 2015

Set first line (instead shebang): //usr/bin/env go run $0 "$@"; exit
and run:

 chmod 744 script.go
 ./script.go 1 2

Copy link

dlukes commented Jun 9, 2015

very nice, thanks a lot! I had no idea shebangs were so flexible :) (I know, it's all up there on wikipedia, but it seemed like such a trivial topic that it never occurred to me to dig deeper. thanks for enlightening me!)

Copy link

AzTruLRD commented Dec 29, 2016

I need to execute a GoLang code as a bash script. Can i use this //usr/bin/env go run $0 "$@"; exit to execute my code without compile it?
Just running it like ./my_file.go

If your answer is yes, i was trying to use it but i got this //usr/bin/env: No such file or directory and another question, what means the number 1 and 2 after ./script.go ??

Thanks a lot :)

Copy link

msoap commented Jan 2, 2017

Usage /usr/bin/env - depends of OS. What printed for which env or type env?

1 and 2 - this is script parameters example.

Copy link

estraph commented May 3, 2017

@msoap I'm curious about how this works. I've been digging into the shebang and magic numbers, but there doesn't seem to be official support for a // (0x2F 0x2F) magic number. My understanding is that by doing this, the executable file will be run as a shell script (somehow by default?), and that it runs the whole first line (including the //), which happens to work fine (//usr/bin/env is valid). If it was a magic number, then the // would be skipped.

Do you have any details on how this works, and how well supported it would be in mainstream shells?

UPDATE to answer my own question: if no shebang is present, and if the executable type can't otherwise be determined via a suitable magic number, then the legacy UNIX behaviour is to run the file as a script with /bin/sh. In this case, it's launching the script with sh, which in turn launches env and go run, only to exit after.


Nice one!

Copy link

msoap commented May 5, 2017

Yes, run is through /bin/sh

Copy link

msoap commented Mar 16, 2018

Copy link

artheus commented Aug 22, 2018

I would add one thing. I haven't tester that it work properly. But adding $? as argument to exit, should allow exit code to be set properly.

Copy link

msoap commented Sep 3, 2018

Unfortunately, this does not work properly. The exit code is always 1 or 0.

Copy link

@msoap There is no way to get the correct error code from go run, unfortunately. See here:

Copy link

pdk commented Oct 4, 2020

I tested (very briefly) on macos with os.Exit(1) and os.Exit(7). What I see in this env is that the exit code is propagated, and can be captured with $? in the calling shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment