运行命令并在线获取输出 [英] Running command and get the output online

查看:93
本文介绍了运行命令并在线获取输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用下面的代码,它的工作原理是问题是输出打印就像执行完成的进程一样,
我希望将输出直接打印到屏幕上,并且在进程执行时不提供所有输出完成后,我该怎么做到这一点?

I use the following code which works, The problem is that the output is printed just as the process finished to execute, I want to print to the screen the output live and not provide all the output when the process finishes, how can I achieve this?

cmdParams := [][]string{
    {filepath.Join(dir,path), "npm", "install"},
    {filepath.Join(pdir,n.path), "gulp"},
}

for _, cp := range cmdParams {
    log.Printf("Starting %s in folder %s...", cp[1:], cp[0])
    cmd := exec.Command(cp[1], cp[2:]...)
    cmd.Dir = cp[0]
    // Wait to finish, get output:
    out, err := cmd.Output()
    if err != nil {
        log.Printf("Error running %s: %v\n", cp[1:], err)
        return
    }
    log.Println("Finished %s, output: %s", cp[1:], out)
}

更新在尝试提出的解决方案时,我得到了如下输出:

update when trying the proposed solution I got the output like

2018/02/18 11:11:57  Starting [npm install] in folder ...
2018/02/18 11:12:14 adde
2018/02/18 11:12:14 d 56
2018/02/18 11:12:14 3 pa
2018/02/18 11:12:14 ckag
2018/02/18 11:12:14 es i
2018/02/18 11:12:14 n 15
2018/02/18 11:12:14 .477
2018/02/18 11:12:14 s
2018/02/18 11:12:14 Finished %s [npm install]


推荐答案

使用本答案中提供的解决方案:流式处理命令输出进度

Using the solution presented in this answer: Streaming commands output progress

cmdParams := [][]string{
    {filepath.Join(dir, path), "npm", "install"},
    {filepath.Join(pdir, n.path), "gulp"},
}
for _, cp := range cmdParams {
    log.Printf("Starting %s in folder %s...", cp[1:], cp[0])
    cmd := exec.Command(cp[1], cp[2:]...)
    cmd.Dir = cp[0]

    stdout, err := cmd.StdoutPipe()
    if err != nil {
        log.Printf("%s cmd.StdoutPipe() error: %v\n", cp[1:], err)
        return
    }
    // Start command:
    if err = cmd.Start(); err != nil {
        log.Printf("%s start error: %v\n", cp[1:], err)
        return
    }

    // Stream command output:
    scanner := bufio.NewScanner(stdout)
    scanner.Split(bufio.ScanRunes)
    for scanner.Scan() {
        fmt.Print(scanner.Text())
    }
    if scanner.Err() != nil {
        log.Printf("Reading %s stdout error: %v\n", cp[1:], err)
        return
    }

    // Get execution success or failure:
    if err = cmd.Wait(); err != nil {
        log.Printf("Error running %s: %v\n", cp[1:], err)
        return
    }
    log.Printf("Finished %s", cp[1:])
}

这行:

This line:

scanner := bufio.NewScanner(stdout)

创建 bufio.Scanner ,它将从提供进程写入输出的管道中读取。

Creates a bufio.Scanner that will read from the pipe that supplies the output written by the process.

这行:

This line:

scanner.Split(bufio.ScanRunes)

指示扫描器通过 rune s读取输入,而不是默认的行。

Instructs the scanner to read the input by runes instead of the default by-lines.

请注意,上面的示例只会传输进程的标准输出。如果您还需要其标准错误流,则还可以阅读 Command.StderrPipe()

Note that the above example only streams the standard output of the process. If you also need its standard error stream, you could also read from Command.StderrPipe().

另外请注意,这不适用于某些不会写入所有内容的命令到他们的标准输出或错误。有关详细信息,请参阅如何在golang中获得shell命令的实时输出?

Also note that this won't work with some commands that don't write everything to their standard output or error. For details, see How to get the realtime output for a shell command in golang?

这篇关于运行命令并在线获取输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆