如何在golang中获取shell命令的实时输出? [英] How to get the realtime output for a shell command in golang?

查看:895
本文介绍了如何在golang中获取shell命令的实时输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在golang中使用os / exec调用shell命令,该命令需要一些时间,所以我想要检索重新输出并输出处理后的输出(进度比率编号)。 b
$ b

 包裹主要

进口(
bufio
fmt
io
os
os / exec
strings


func main(){
cmdName:= ffmpeg -i t.webm -acodec aac -vcodec libx264 cmd1.mp4
cmdArgs:= strings.Fields(cmdName)
$ b cmd:= exec.Command(cmdArgs [0], cmdArgs [1:len(cmdArgs)] ...)
stdout,_:= cmd.StdoutPipe()
cmd.Start()
打印(stdout)
cmd .Wait()
}

//当stdout获得新行时打印处理后的信息
func print(stdout io.ReadCloser){
r:= bufio .NewReader(stdout)
line,_,err:= r.ReadLine()
fmt.Println(line:%s err%s,line,err)
}

我想要哈有一个函数可以在命令输出时更新屏幕,

ffmpeg命令输出如下:

  frame = 101 fps = 0.0 q = 28.0 size = 91kB time = 00:00:04.13 bitrate = 181.2kbits / 
frame = 169 fps = 168 q = 28.0 size = 227kB时间= 00:00:06.82比特率= 272.6kbits /
帧= 231 fps = 153 q = 28.0大小= 348kB时间= 00:00:09.31比特率= 306.3kbits /
帧= 282 fps = 140 q = 28.0 size = 499kB time = 00:00:11.33 bitrate = 360.8kbits /

,上面的4行是ffmpeg命令输出的最后一行,它不断变化,我想打印出来,比如

  18%
44%
69%
100%

我可以做到这一点?

解决方案

看起来像ffmpeg发送所有诊断消息(控制台输出)
stderr 而不是stdout。下面的代码适用于我。

  package main 

import(
bufio
fmt
os / exec
strings


func main(){
args:=-i test.mp4 -acodec copy -vcodec copy -f flv rtmp:// aaa / bbb
cmd:= exec.Command(ffmpeg,strings.Split(args,)...)

stderr,_:= cmd.StderrPipe()
cmd.Start()

scanner:= bufio.NewScanner(stderr)
scanner.Split(bufio.ScanWords)
for scanner.Scan(){
m:= scanner.Text()
fmt.Println(m)
}
cmd.Wait()
}

ffmpeg的版本详述如下。

  ffmpeg版本3.0.2 Copyright(c)2000-2016使用Apple LLVM 7.3版建立的FFmpeg开发者
。 0(clang-703.0.29)
配置:--prefix = / usr / local / Cellar / ffmpeg / 3.0.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc = clang --host-cflags = --host-ldflags = --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid - -enable-vda
libavutil 55. 17.103 / 55. 17.103
libavcodec 57. 24.102 / 57. 24.102
libavformat 57. 25.100 / 57. 25.100
libavdevice 57. 0.101 / 57 0.101
libavfilter 6. 31.100 / 6. 31.100
libavresample 3. 0. 0 / 3. 0.0
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100


I am trying to call shell command with os/exec in golang, that command will take some time, so I would like to retrieve the reatime output and print the processed output (a progressing ratio number).

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "os/exec"
    "strings"
)

func main() {
    cmdName := "ffmpeg -i t.webm  -acodec aac -vcodec libx264  cmd1.mp4"
    cmdArgs := strings.Fields(cmdName)

    cmd := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
    stdout, _ := cmd.StdoutPipe()
    cmd.Start()
    go print(stdout)
    cmd.Wait()
}

// to print the processed information when stdout gets a new line
func print(stdout io.ReadCloser) {
    r := bufio.NewReader(stdout)
    line, _, err := r.ReadLine()
    fmt.Println("line: %s err %s", line, err)
}

I want to have a function where can update the screen when the command print something,

The ffmpeg command output is as follows:

frame=  101 fps=0.0 q=28.0 size=      91kB time=00:00:04.13 bitrate= 181.2kbits/
frame=  169 fps=168 q=28.0 size=     227kB time=00:00:06.82 bitrate= 272.6kbits/
frame=  231 fps=153 q=28.0 size=     348kB time=00:00:09.31 bitrate= 306.3kbits/
frame=  282 fps=140 q=28.0 size=     499kB time=00:00:11.33 bitrate= 360.8kbits/

in fact, the above 4 line is the last line of ffmpeg command output which keeps changing, I want to print that change out, like

18%
44%
69%
100%

how could I achieve this?

解决方案

Looks like ffmpeg sends all diagnostic messages (the "console output") to stderr instead of stdout. Below code works for me.

package main

import (
    "bufio"
    "fmt"
    "os/exec"
    "strings"
)

func main() {
    args := "-i test.mp4 -acodec copy -vcodec copy -f flv rtmp://aaa/bbb"
    cmd := exec.Command("ffmpeg", strings.Split(args, " ")...)

    stderr, _ := cmd.StderrPipe()
    cmd.Start()

    scanner := bufio.NewScanner(stderr)
    scanner.Split(bufio.ScanWords)
    for scanner.Scan() {
        m := scanner.Text()
        fmt.Println(m)
    }
    cmd.Wait()
}

The version of ffmpeg is detailed as below.

ffmpeg version 3.0.2 Copyright (c) 2000-2016 the FFmpeg developers
built with Apple LLVM version 7.3.0 (clang-703.0.29)
configuration: --prefix=/usr/local/Cellar/ffmpeg/3.0.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --enable-vda
libavutil      55. 17.103 / 55. 17.103
libavcodec     57. 24.102 / 57. 24.102
libavformat    57. 25.100 / 57. 25.100
libavdevice    57.  0.101 / 57.  0.101
libavfilter     6. 31.100 /  6. 31.100
libavresample   3.  0.  0 /  3.  0.  0
libswscale      4.  0.100 /  4.  0.100
libswresample   2.  0.101 /  2.  0.101
libpostproc    54.  0.100 / 54.  0.100

这篇关于如何在golang中获取shell命令的实时输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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