可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a go program that should invoke a ruby script.
I have a runCommand function:
func runCommand(cmdName string, arg ...string) { cmd := exec.Command(cmdName, arg...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin err = cmd.Run() if err != nil { fmt.Printf("Failed to start Ruby. %s\n", err.Error()) os.Exit(1) } }
I invoke it like this:
runCommand("ruby", "-e", "require 'foo'")
It works for most cases, except if there is a gets or any similar operation in the child process that needs to pause for an input.
I have tried setting cmd.Stdin = os.Stdin, but it does not wait for input.
What am I doing wrong?
回答1:
The following program seems do what you ask for (my runCommand is almost identical to yours. I just changed the = to := for the err line.) Are you doing something differently?
package main import ( "fmt" "os" "os/exec" ) func main() { runCommand("ruby", "-e", `puts "Running"; $in = gets; puts "You said #{$in}"`) } func runCommand(cmdName string, arg ...string) { cmd := exec.Command(cmdName, arg...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin err := cmd.Run() if err != nil { fmt.Printf("Failed to start Ruby. %s\n", err.Error()) os.Exit(1) } }
回答2:
You might need to use a pseudoterminal. You can do this in go with this library: github.com/kr/pty:
package main import ( "bufio" "io" "log" "os" "os/exec" "github.com/kr/pty" ) func runCommand(cmdName string, arg ...string) { cmd := exec.Command(cmdName, arg...) tty, err := pty.Start(cmd) if err != nil { log.Fatalln(err) } defer tty.Close() go func() { scanner := bufio.NewScanner(tty) for scanner.Scan() { log.Println("[" + cmdName + "] " + scanner.Text()) } }() go func() { io.Copy(tty, os.Stdin) }() err = cmd.Wait() if err != nil { log.Fatalln(err) } } func main() { log.SetFlags(0) runCommand("ruby", "-e", ` puts "Enter some text" text = gets puts text `) }