Ok, that's a great explanation, thanks. Do you have a recommendation for how to 
exit early? Would StdoutPipe() help? I tried setting Setpgid to true, but 
probably os/exec doesn't pay attention to process groups.

Alternatively, I can configure my shell scripts to close stdout/err on exit? 
Not pretty, but might work.

My best approach so far is to use time.After and panic, instead of context. 
This code is being used in a test, so panic is somewhat acceptable.

Thanks again.




On 9/29/17, 1:26 PM, "Ian Lance Taylor" <i...@golang.org> wrote:

>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.

Reply via email to