我有一个应该调用ruby脚本的go程序。
我有一个runCommand
功能:
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)
}
}
我这样调用它:
runCommand("ruby", "-e", "require 'foo'")
它适用于大多数情况,除非子进程中有gets
或任何类似的操作需要暂停输入。
我已尝试设置cmd.Stdin = os.Stdin
,但它不会等待输入。
我做错了什么?
答案 0 :(得分:5)
以下程序似乎按照您的要求执行(我的runCommand
几乎与您的相同。我刚刚将=
更改为:=
行的err
。)你有不同的做法吗?
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)
}
}
答案 1 :(得分:4)
您可能需要使用pseudoterminal。您可以使用此库执行此操作: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
`)
}