首先,我从中构建一个名为exec.exe的命令:
package main
import "fmt"
func main() {
var input string
fmt.Println("input a value")
fmt.Scanln(&input)
fmt.Println(input)
fmt.Println("input another value")
fmt.Scanln(&input)
fmt.Println(input)
}
然后我要使用os / exec pacage来运行它:
package main
import (
"fmt"
"os/exec"
)
func main() {
cmd := exec.Command("G:\\go_workspace\\GOPATH\\src\\pjx\\modules\\exec\\exec")
stdin, e := cmd.StdinPipe()
if e != nil {
panic(e)
}
stdout, e := cmd.StdoutPipe()
if e != nil {
panic(e)
}
if e:=cmd.Start();e!=nil {
panic(e)
}
stdin.Write([]byte("hello"))
var buf = make([]byte, 512)
n, e := stdout.Read(buf)
if e != nil {
panic(e)
}
fmt.Println(string(buf[:n]))
if e := cmd.Wait(); e != nil {
panic(e)
}
}
最后我运行它,结果将在用户输入阶段暂停,例如:
(如果未加载图片,则在输入阶段将其暂停)
please input a value:
1
12
232
我是否以错误的方式使用了cmd管道?
答案 0 :(得分:1)
您需要监听正在执行的程序的输出。当您编写“ hello”时,该程序可能仍在写入其标准输出。试试这个:
go func() {
in := bufio.NewReader(stdout)
for {
s, err := in.ReadString('\n')
if err != nil {
return
}
fmt.Println(s)
}
}()
if e := cmd.Start(); e != nil {
panic(e)
}
stdin.Write([]byte("hello\n"))
stdin.Write([]byte("hello2\n"))
if e := cmd.Wait(); e != nil {
panic(e)
}
答案 1 :(得分:1)
一种方法
cmd := exec.Command("...") // Change to your path
stdin, err := cmd.StdinPipe()
if err != nil {
panic(err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}
buf := bytes.NewBuffer(nil)
// read the stdout continuously in a separate goroutine and capture it in buf
go func() {
io.Copy(buf, stdout)
}()
if err := cmd.Start(); err != nil {
panic(err)
}
stdin.Write([]byte("hello\n")) // Send \n to submit
stdin.Write([]byte("world\n"))
if err := cmd.Wait(); err != nil {
panic(err)
}
fmt.Fprint(os.Stdout, buf)
结果:
➜ go run main.go input a value hello input another value world
答案 2 :(得分:1)
程序正在阻塞,因为子进程中的jar{
baseName = "libdemo"
version = "1.0"
manifest {
attributes ('Main-Class': 'com.example.lib.Main')
}
from {
configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) }
}
}
正在等待fmt.Scanln
字符(\n
也将使其返回)。为避免阻塞,您的输入应包括两个EOF
,或者您可以仅调用'stdin.Close()'来指示输入流已完成。
并且由于子流程多次调用\n
和Scanln
,因此对Println
的单次调用可能无法读取子流程的完整输出。您可以继续调用stdout.Read
,直到返回stdout.Read()
错误为止,也可以只使用io.EOF
。
ioutil.ReadAll