-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
What version of Go are you using (go version)?
$ go version go version go1.17.6 linux/amd64
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/[REDACTED]/.cache/go-build" GOENV="/home/[REDACTED]/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/[REDACTED]/go/pkg/mod" GONOPROXY="[REDACTED],[REDACTED]/*,github.com/[REDACTED]/*" GONOSUMDB="[REDACTED],[REDACTED]/*,github.com/[REDACTED]/*" GOOS="linux" GOPATH="/opt/dev/go" GOPRIVATE="[REDACTED],[REDACTED]/*,github.com/[REDACTED]/*" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/lib/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.17.6" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/[REDACTED]/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1498898721=/tmp/go-build -gno-record-gcc-switches"
What did you do?
N/A; bug in design.
exec.Cmd.Run() currently returns an error on non-zero exit status.
This is not only poor design logic as many commands return non-zero even upon success, but it hampers access to getting the status code of a command- requiring .Wait() to be invoked instead.
A careful note is that it's common assumption that POSIX or some other standard defines 0 as success and n > 0 as failure. To stress, this is erroneous - it is convention, not standard.
An immediate example that comes to mind is sendmail's EX_TEMPFAIL, status code 75. This indicates that a message was deferred, not failed, and will be retried (or the user should retry, depending on your MTA spooling or lack thereof).
What did you expect to see?
N/A
What did you see instead?
N/A
Proposed Resolution
I propose the following.
Obviously changing e.g. exec.Run() execution with a non-zero exit code flagging an error is not the proper way forward, as that's a significant API interface change that likely many people are depending on.
Instead, there should be "non-erroring" methods added, e.g. .RunNonZero() and .WaitNonZero() (I'm not crazy about the names, but...) that will return the *os.ProcessState (nil if error NOT related to command exit code) and error (NOT returned if command has non-zero exit code).