Fork me on GitHub
随笔 - 209  文章 - 13  trackbacks - 0
<2016年9月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678


专注即时通讯及网游服务端编程
------------------------------------
Openresty之lua-nginx-module
------------------------------------
本博收藏大部分文章为转载,并在文章开头给出了原文出处,如有再转,敬请保留相关信息,这是大家对原创作者劳动成果的自觉尊重!!如为您带来不便,请于本博下留言,谢谢配合。

常用链接

留言簿

随笔分类

随笔档案

相册

Awesome

Blog

Book

GitHub

Link

搜索

  •  

积分与排名

  • 积分 - 58841
  • 排名 - 317

最新评论

阅读排行榜

https://blog.csdn.net/windvix/article/details/44222629

Golang运行cmd命令逐行实时输出执行过程,注意,不是一次输出所有的内容,而是按照执行的过程,逐行逐行的实时显示出来

代码如下:

package main
 
import (
    "bufio"
    "fmt"
    "io"
    "os/exec"
)
 
func main() {
    command := "ls"
    params := []string{"-l"}
    //执行cmd命令: ls -l
    execCommand(command, params)
}
 
func execCommand(commandName stringparams []stringbool {
    cmd := exec.Command(commandName, params)
 
    //显示运行的命令
    fmt.Println(cmd.Args)
 
    stdout, err := cmd.StdoutPipe()
 
    if err != nil {
        fmt.Println(err)
        return false
    }
    
    cmd.Start()
 
    reader := bufio.NewReader(stdout)
 
    //实时循环读取输出流中的一行内容
    for {
        line, err2 := reader.ReadString('\n')
        if err2 != nil || io.EOF == err2 {
            break
        }
        fmt.Println(line)
    }
 
    cmd.Wait()
    return true
}

编译运行效果如图:


http://www.tianfeiyu.com/?p=2673

Golang 中可以使用 os/exec 来执行 Linux 命令,下面是一个简单的示例:

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os/exec"
  6. )
  7. func main() {
  8. cmd := exec.Command("/bin/bash", "-c", `df -lh`)
  9. //创建获取命令输出管道
  10. stdout, err := cmd.StdoutPipe()
  11. if err != nil {
  12. fmt.Printf("Error:can not obtain stdout pipe for command:%s\n", err)
  13. return
  14. }
  15. //执行命令
  16. if err := cmd.Start(); err != nil {
  17. fmt.Println("Error:The command is err,", err)
  18. return
  19. }
  20. //读取所有输出
  21. bytes, err := ioutil.ReadAll(stdout)
  22. if err != nil {
  23. fmt.Println("ReadAll Stdout:", err.Error())
  24. return
  25. }
  26. if err := cmd.Wait(); err != nil {
  27. fmt.Println("wait:", err.Error())
  28. return
  29. }
  30. fmt.Printf("stdout:\n\n %s", bytes)
  31. }

或者创建一个缓冲读取器按行读取:

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os/exec"
  6. )
  7. func main() {
  8. cmd := exec.Command("/bin/bash", "-c", `df -lh`)
  9. //创建获取命令输出管道
  10. stdout, err := cmd.StdoutPipe()
  11. if err != nil {
  12. fmt.Printf("Error:can not obtain stdout pipe for command:%s\n", err)
  13. return
  14. }
  15. //执行命令
  16. if err := cmd.Start(); err != nil {
  17. fmt.Println("Error:The command is err,", err)
  18. return
  19. }
  20. //使用带缓冲的读取器
  21. outputBuf := bufio.NewReader(stdout)
  22. for {
  23. //一次获取一行,_ 获取当前行是否被读完
  24. output, _, err := outputBuf.ReadLine()
  25. if err != nil {
  26.  
  27. // 判断是否到文件的结尾了否则出错
  28. if err.Error() != "EOF" {
  29. fmt.Printf("Error :%s\n", err)
  30. }
  31. return
  32. }
  33. fmt.Printf("%s\n", string(output))
  34. }
  35. //wait 方法会一直阻塞到其所属的命令完全运行结束为止
  36. if err := cmd.Wait(); err != nil {
  37. fmt.Println("wait:", err.Error())
  38. return
  39. }
  40. }

输出结果:

在写这句 if err.Error() != "EOF" 时,一直以为可以直接将 error 类型直接转为 string 然后就可以比较了,所以刚开始写的代码是这样的 if string(err) != "EOF",但是一直报下面这个错误:

  1. # command-line-arguments
  2. ./exec_command.go:36: cannot convert err (type error) to type string

于是查了下才明白,error 类型本身是一个预定义好的接口,里面定义了一个method

  1. type error interface {
  2. Error() string
  3. }
    //
     err.Error() 才是一个 string 类型的返回值。
posted on 2018-10-09 16:09 思月行云 阅读(23) 评论(0)  编辑 收藏 引用 所属分类: Golang

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理