go - 连续读取 exec.Cmd 输出

标签 go exec stdout

伙计们,我正在尝试从命令输出中选择新行,但我总是以同步方式结束(我必须等到脚本完成)。我厌倦了使用 fsnotify,但它只能处理常规文件,您知道如何完成吗?

package main
import (
   "fmt"
   "os/exec"
   "bytes"
   "os"
)

func main() {
   cmd := exec.Command("scripts/long_script")
   output := new(bytes.Buffer)
   cmd.Stdout = output
   cmd.Stderr = output
   if err := cmd.Start(); err != nil{ // after Start program is continued and script is executing in background
     fmt.Printf("Failed to start " + err.Error())
     os.Exit(1)
   }
   fmt.Printf(" Before WAIT %s \n", output.String())  // script is writing but nothing can be read from output
   cmd.Wait()
   fmt.Printf(" After Wait %s \n", output.String())  // if we wait to finish execution, we can read all output
}

最佳答案

你应该使用 os.StdoutPipe()

func main() {
    for i := 10; i < 20; i++ {
        go printName(`My name is Bob, I am ` + strconv.Itoa(i) + ` years old`)
        // Adding delay so as to see incremental output
        time.Sleep(60 * time.Millisecond)
    }
    // Adding delay so as to let program complete
    // Please use channels or wait groups
    time.Sleep(100 * time.Millisecond)
}

func printName(jString string) {
    cmd := exec.Command("echo", "-n", jString)
    cmdReader, err := cmd.StdoutPipe()
    if err != nil {
        log.Fatal(err)
    }
    scanner := bufio.NewScanner(cmdReader)
    go func() {
        for scanner.Scan() {
            fmt.Println(scanner.Text())
        }
    }()
    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }
    if err := cmd.Wait(); err != nil {
        log.Fatal(err)
    }
}

对我有帮助的资源: nathanleclaire.com blog.kowalczyk.info

关于go - 连续读取 exec.Cmd 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43635611/

相关文章:

我可以将 argv 从 main 传递到 execv 吗?

c - 将标准输出重定向到 C 中的变量

c++ - 是否保证标准输出在退出前自动刷新?它是如何工作的?

Gorilla/Mux 反向映射 URL

go - 试图了解如何在我的项目和包中查找结构

sorting - 根据值的出现次数对 slice 进行排序

linux - C 中的破管道——pipe()、fork()、exec() 程序

go - Go Web App 中必须要有 DAL 和 BLL 吗?

c - 如何使用 execlp() 查找 pid?

bash - Shell 已输出但无法通过管道输出数据