I pointed out that maybe exec.Cmd.StdinPipe and exec.Cmd.StdoutPipe would be better. Here’s the *modified* sample from this thread and the complete program for easier copying to play with—no deadlock with this. func main() { defer err2.Catch() cmdName := "/bin/bash" cmdArgs := []string{ "-c", "sleep 5"} cmd := exec.Command(cmdName, cmdArgs...) cmdStdinW := try.To1(cmd.StdinPipe()) cmdStdoutR := try.To1(cmd.StdoutPipe()) go func() { defer err2.Catch() // No need to close the pipes try.To1(io.Copy(cmdStdinW, cmdStdoutR)) fmt.Println("copier ends") }() try.To(cmd.Start()) // we cannot use just Run() with Cmd.XxxPipe calls... try.To(cmd.Wait()) // ... according to docs fmt.Println("all OK") }
The entire program sample: package main import ( "fmt" "io" "os/exec" "github.com/lainio/err2" "github.com/lainio/err2/try" ) func main() { defer err2.Catch() cmdName := "/bin/bash" cmdArgs := []string{"-c", "sleep 5"} cmd := exec.Command(cmdName, cmdArgs...) cmdStdinW := try.To1(cmd.StdinPipe()) cmdStdoutR := try.To1(cmd.StdoutPipe()) go func() { defer err2.Catch() // No need to close the pipes try.To1(io.Copy(cmdStdinW, cmdStdoutR)) fmt.Println("copier ends") }() try.To(cmd.Start()) // we cannot use just Run() with Cmd.XxxPipe calls... try.To(cmd.Wait()) // ... according to docs fmt.Println("all OK") } On Tuesday, June 18, 2024 at 7:47:06 AM UTC+3 Ian Lance Taylor wrote: > On Mon, Jun 17, 2024 at 7:49 PM Salvatore Domenick Desiano > <near...@gmail.com> wrote: > > > > Here's a hopefully semantically identical minimal example: > > > > func main() { > > > > cmdName := "/bin/bash" > > cmdArgs := []string{"-c", "sleep 5"} > > cmdStdinR, cmdStdinW := io.Pipe() > > cmdStdoutR, cmdStdoutW := io.Pipe() > > go func() { > > > > defer cmdStdinW.Close() > > > > io.Copy(cmdStdinW, cmdStdoutR) > > > > }() > > cmd := exec.Command(cmdName, cmdArgs...) > > cmd.Stdout = cmdStdoutW > > cmd.Stdin = cmdStdinR > > if err := cmd.Run(); err != nil { > > > > fmt.Println(err) > > > > } > > > > } > > > > This program deadlocks after seconds. The three locked Go routines are > the io.Copy( (stuck inside io.Copy because cmdStdoutR doesn't close), the > exec.Command Go routine (also stuck in an io.Copy) and the main routine > (stuck in cmd.Wait()). > > > I haven't checked whether this is the problem, but as someone else > pointed out this is a strange place to use io.Pipe. Much better to > use os.Pipe. Much better still to use exec.Cmd.StdinPipe and > exec.Cmd.StdoutPipe. > > 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. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/53ebdd3a-9f8a-4a42-8575-6c0ecd75e850n%40googlegroups.com.