Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: go run always returns exit code 1, no matter what the real exit code was #13440

Closed
viktorbenei opened this issue Dec 1, 2015 · 13 comments

Comments

@viktorbenei
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.5.1 darwin/amd64

What operating system and processor architecture are you using?

Mac OS X 10.11.1

What did you do?

Saved this Go program into main.go:

package main

import "os"

func main() {
    os.Exit(3)
}

And then ran go run main.go:

$ go run main.go
exit status 3
$ echo $?
1

What did you expect to see?

$ echo $? should be 3 instead of 1

What did you see instead?

The exit code reported by $ echo $? is always 1 if the program exits with a non zero exit code.

If you compile the example with $ go build -o gotest it returns the expected exit code:

$ ./gotest
$ echo $?
3
@ianlancetaylor ianlancetaylor changed the title go run always returns exit code 1, no matter what the real exit code was cmd/go: go run always returns exit code 1, no matter what the real exit code was Dec 1, 2015
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Dec 1, 2015
@ianlancetaylor
Copy link
Contributor

In the general case we can't recreate the right exit status, but I suppose we could pass along an ordinary exit code.

@viktorbenei
Copy link
Author

I think the exit code would be enough, just to be able to use go run ... from other tools, without requiring a go build first. Context: we do this for smaller scripts, where we use Go like a scripting language, instead of Ruby / Python / etc.

@gopherbot
Copy link

CL https://golang.org/cl/18271 mentions this issue.

@rsc
Copy link
Contributor

rsc commented Jan 6, 2016

Not for Go 1.6.

@rsc
Copy link
Contributor

rsc commented Jan 6, 2016

From code review:

What if it crashed due to a signal? Now it's exit(someRandomNumber).
I am not convinced this needs to be done at all.

It won't exit with some random number if it fails with a signal.
It will exit with status 1 as it did before.

Fair enough, let me try again:

What if it crashed due to a signal?
It used to print information about the exit reason and exit 1.
Now it's a silent exit(someRandomNumber).

The real question is whether 'go run x.go' is supposed to be just an interpreter for Go programs, like 'python x.py' or whether it is a tool that runs a subprocess and reports the results itself, like make. To date, the answer has been the latter. So it's not obvious the behavior is wrong, unless 'go run' is supposed to be some kind of interactive go command, which we've said in the past it is not.

$ cat makefile
exit5:
    exit 5
$ make exit5
exit 5
make: *** [exit5] Error 5
$ echo $?
2
$ 

(Make happens to use 2 instead of 1, but it's always 2 on my system.)

$ cat x.go
package main

import "os"

func main() {
    os.Exit(5)
}
$ go run x.go
exit status 5
$ echo $?
1
$ 

@dmitshur
Copy link
Contributor

I agree with Russ for the reasons he stated.

An exit code is a single-dimensional value. When doing go run, there are 2 processes that run and 2 exit codes one may want to know.

However, go run is only able to report a single exit code value, not two. It's not possible to losslessly combine two exit codes into one. If it reported the exit code of the program it ran verbatim, then information about the go run exit code would be shadowed and effectively lost.

IMO, if one cares about the exact exit code of the program that is executed, they need to build it and execute it themselves. go run is a convenience feature for when your needs are not as demanding and you're okay with less information, because it's unable to communicate more information than it already does.

@bradfitz
Copy link
Contributor

I think this is effectively closed.

@mattn
Copy link
Member

mattn commented May 11, 2016

I updated the CL to fix only windows and unix. Still wrong?

@mattn
Copy link
Member

mattn commented May 11, 2016

@shurcooL how about to add new flag to return status code (non-1) of the exit code from go run?

@davecheney
Copy link
Contributor

Please, no more flags. Go run is for toy programs, if you have a serious
program then build and run it seriously.

On Wed, 11 May 2016, 13:26 mattn, notifications@github.com wrote:

@shurcooL https://github.com/shurcooL how about to add new flag to
return status code (non-1) of the exit code from go run?


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#13440 (comment)

@mattn
Copy link
Member

mattn commented May 11, 2016

@davecheney So do you think https://github.com/sno6/gommand this should do go build -o myapp && ./myapp it self if he want exit code of the program?

@davecheney
Copy link
Contributor

My advice that Go run is a toy, and adding more features to it to make it
more capable is moving in the wrong direction. The rest of the go tool is
focused on code placed in packages and built and tested as such.

On Wed, 11 May 2016, 13:32 mattn, notifications@github.com wrote:

@davecheney https://github.com/davecheney So do you think
https://github.com/sno6/gommand this should do go build -o myapp &&
./myapp it self if he want exit code of the program?


You are receiving this because you were mentioned.

Reply to this email directly or view it on GitHub
#13440 (comment)

@mattn
Copy link
Member

mattn commented May 11, 2016

Okay, agreed. Thanks.

@golang golang locked and limited conversation to collaborators May 11, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants