如何使用golang os\exec包,操控一个交互试命令程序?

新手上路,请多包涵
首先下面代码是有问题,大佬看一下代码,这个输入这里应该有问题,或者这个库不支持这样的持续交互吗?
package main

import (
    "fmt"
    "io"
    "os/exec"
    "time"
)

func main() {
    // 进行字符串的替换,把小写字母替换成大写字母
    cmd := exec.Command("tr", "a-z", "A-Z")
    var (
        err    error
        stdout io.ReadCloser
        stdin  io.WriteCloser
    )
    stdout, err = cmd.StdoutPipe()
    if err != nil {
        panic(err)
    }
    stdin, err = cmd.StdinPipe()
    if err != nil {
        panic(err)
    }
    if err = cmd.Start(); err != nil {
        panic(err)
    }
    // 这里协程给tr命令输入标准输入的 小写 abc 字符串
    go func() {
        for {
            time.Sleep(time.Second)
            stdin.Write([]byte("abc"))
        }
    }()

    // 然后这里从标准输出读到上面输入后tr命令转换后的大写字符串 ABC,但这里没有读到,不知道为什么
    for {
        data := make([]byte, 512)
        n, err := stdout.Read(data)

        fmt.Println(string(data[:n]), err)
    }
}
阅读 1.4k
avatarAI BotBETA

这段代码的问题在于,stdoutstdin 的类型是 io.ReadCloserio.WriteCloser,但是 StdoutPipe()StdinPipe() 返回的管道类型实际上是 io.Readerio.Writer。因此,我们需要将 stdoutstdin 的类型更改为 io.Readerio.Writer

以下是修改后的代码:

package main

import (
 "fmt"
 "io"
 "os/exec"
 "time"
)

func main() {
 // 进行字符串的替换,把小写字母替换成大写字母
 cmd := exec.Command("tr", "a-z", "A-Z")
 var (
 err    error
 stdout io.ReadCloser
 stdin  io.WriteCloser
 )
 stdout, err = cmd.StdoutPipe()
 if err != nil {
 panic(err)
 }
 stdin, err = cmd.StdinPipe()
 if err != nil {
 panic(err)
 }
 // 这里协程给tr命令输入标准输入的 小写 abc 字符串
 go func() {
 for {
 time.Sleep(time.Second)
 stdin.Write([]byte("abc"))
 }
 }()

 // 然后这里从标准输出读到上面输入后tr命令转换后的大写字符串 ABC
 for {
 data := make([]byte, 512)
 n, err := stdout.Read(data)
 if err != nil {
 fmt.Println(err)
 break
 }
 fmt.Println(string(data[:n]))
 }
}

在这个修改后的代码中,我们将 stdoutstdin 的类型更改为 io.Readerio.Writer,然后从 stdout 中读取转换后的大写字符串。现在应该可以正常读取到输出结果了。

1 个回答
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题