-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
os/exec: document that you must call Wait before accessing copied output #24220
Comments
I can confirm that the repro works in my machine. It has something to do with killing the process after it has written to the buffer. This program gives correct output in both 1.10 and 1.9. package main
import (
"os/exec"
"bytes"
"fmt"
)
func main() {
c := exec.Command("/bin/bash", "-c", "echo abc && sleep 10")
var outBuf bytes.Buffer
c.Stdout = &outBuf
if err := c.Start(); err != nil {
panic(err)
}
if err := c.Wait(); err != nil {
panic(err)
}
fmt.Println(outBuf.Bytes())
} |
This program has a data race, which you will see if you run it under the race detector. As @agnivade suggests, the problem is that you are accessing the output buffer before calling I don't think there is a bug in the code, but I don't see anything in the documentation that clarifies that you need to call |
Thanks Ian. Does that mean when |
The issue is that you are using bash to start new processes - Call package main
import (
"bytes"
"fmt"
"os/exec"
"time"
)
func main() {
c := exec.Command("/bin/bash", "-c", "echo abc && sleep 10")
var outBuf bytes.Buffer
c.Stdout = &outBuf
if err := c.Start(); err != nil {
panic(err)
}
time.Sleep(3 * time.Second)
if err := c.Process.Kill(); err != nil {
panic(err)
}
if err := c.Wait(); err != nil {
if _, ok := err.(*exec.ExitError); !ok {
panic(err)
}
}
fmt.Println(outBuf.Bytes())
} |
@agnivade are you suggesting that there is no way to kill a process and immediately collect program output generated up to that moment? |
Ah I see, it's just normal process behaviour for |
The "waiting for a tree of processes" problem is #23019. We don't have any approach to "killing a tree of processes" although of course you can put them in a new process group and use We should not have |
Many thanks & have a lovely weekend! |
Change https://golang.org/cl/98395 mentions this issue: |
@ianlancetaylor, I examined the related tickets. The common theme is that programmers do not see from documentation what
Also, |
Your suggested text sounds good to me. I agree that I would rather not get into details about signals. People who understand those issues can use the |
Change https://golang.org/cl/98715 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
The bug does not appear in 1.9.4, therefore it seems to be a regression in 1.10.
What operating system and processor architecture are you using (
go env
)?What did you do?
Run the following piece of code:
Using previous go 1.9.4, the output correctly shows individual bytes in string
abc\n
:However, using go 1.10, the output shows:
Oddly, if the bash command does not say
&& sleep 10
, which means the bash program exits normally before it is killed, both 1.10 and 1.9.4 will collect the correct output[97 98 99 10]
.This is potentially a regression in 1.10.
The text was updated successfully, but these errors were encountered: