On Fri, Sep 29, 2017 at 12:33 PM, Alex Buchanan <buchanae.o...@gmail.com> wrote: > > package main > > import ( > "bytes" > "context" > "log" > "os/exec" > "time" > ) > > func main() { > var stdout bytes.Buffer > > ctx, cancel := context.WithTimeout(context.Background(), time.Second) > defer cancel() > > cmd := exec.CommandContext(ctx, "/bin/sh", "-c", "sleep 10; echo foo") > cmd.Stdout = &stdout > > err := cmd.Run() > log.Printf("%s, %s, '%s'", err, ctx.Err(), stdout.String()) > } > > > This runs for 10 seconds, but I was expecting 1 second. Can someone help me > understand what is happening? I think it has something to do with the stdout > bytes.Buffer?
Yes. The problem is that when the context passed to CommandContext expires, it kills the process started by the command, but does not kill any subprocesses that that command may have started. So when the context expires the /bin/sh is killed, but the sleep subprocess is still running. Because you use a bytes.Buffer, the program has created a pipe to capture the standard output of the command. After the process dies, cmd.Run is waiting for that pipe to be closed to make sure that it gathers all the data. But the pipe is held open by the sleep subprocess. It is only after that subprocess exits that the pipe is closed and your program continues. Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.