-
-
Save msoap/a9ee054f80a58b16867c to your computer and use it in GitHub Desktop.
//usr/bin/env go run $0 "$@"; exit | |
package main | |
import ( | |
"fmt" | |
"os" | |
) | |
func main() { | |
fmt.Println("Hello world!") | |
cwd, _ := os.Getwd() | |
fmt.Println("cwd:", cwd) | |
fmt.Println("args:", os.Args[1:]) | |
} |
@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.
Details: http://www.faqs.org/faqs/unix-faq/faq/part3/section-16.html
Nice one!
Yes, run is through /bin/sh
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.
Unfortunately, this does not work properly. The exit code is always 1 or 0.
@msoap There is no way to get the correct error code from go run
, unfortunately. See here: https://stackoverflow.com/questions/55731760/go-os-exit2-show-a-bash-value-of-1
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.
Usage /usr/bin/env - depends of OS. What printed for
which env
ortype env
?1 and 2 - this is script parameters example.