• go exec 包


    go exec 包

    1 exec 介绍

    有时候我们的go程序需要执行外部的命令,比如执行linux shell命令,一个其他语言编写的二进制文件,我们都可以通过调用go语言的exec包的函数来执行。

    1.1 exec 函数和Cmd的方法

    func Command(name string, arg ...string) *Cmd
    //方法返回一个*Cmd, 用于执行name指定的程序(携带arg参数)
     
    func (c *Cmd) Run() error
    //执行Cmd中包含的命令,阻塞直到命令执行完成
     
    func (c *Cmd) Start() error
    //执行Cmd中包含的命令,该方法立即返回,并不等待命令执行完成
     
    func (c *Cmd) Wait() error
    //该方法会阻塞直到Cmd中的命令执行完成,但该命令必须是被Start方法开始执行的
     
    func (c *Cmd) Output() ([]byte, error)
    //执行Cmd中包含的命令,并返回标准输出的切片
     
    func (c *Cmd) CombinedOutput() ([]byte, error)
    //执行Cmd中包含的命令,并返回标准输出与标准错误合并后的切片
     
    func (c *Cmd) StdinPipe() (io.WriteCloser, error)
    //返回一个管道,该管道会在Cmd中的命令被启动后连接到其标准输入
     
    func (c *Cmd) StdoutPipe() (io.ReadCloser, error)
    //返回一个管道,该管道会在Cmd中的命令被启动后连接到其标准输出
     
    func (c *Cmd) StderrPipe() (io.ReadCloser, error)
    //返回一个管道,该管道会在Cmd中的命令被启动后连接到其标准错误
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2 案例

    2.1 只执行命令,不获取结果

    func main() {
    	cmd := exec.Command("ls", "-l", "/Users/liuqingzheng/")
    	err := cmd.Run()
    	if err != nil {
    		fmt.Println("执行命令出错",err)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.2 执行命令并获取结果

    func main() {
    	cmd := exec.Command("ls", "-l", "/Users/liuqingzheng/")
    	res,err:=cmd.CombinedOutput()
    	if err != nil {
    		fmt.Println(err)
    	}
    	fmt.Println(string(res))
    }
    
    func main() {
    	res,err:= exec.Command("ls", "-l", "/Users/liuqingzheng/").Output()
    	if err != nil {
    		fmt.Println("执行出错:",err)
    	}
    	fmt.Println(string(res))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.3 执行命令,区分stdout 和 stderr

    func main() {
    	cmd := exec.Command("ls", "-l", "/Users/iuqingzheng/*.log")
    	var stdout, stderr bytes.Buffer
    	cmd.Stdout = &stdout  // 标准输出
    	cmd.Stderr = &stderr  // 标准错误
    	err := cmd.Run()
    	outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
    	fmt.Printf("标准输出:\n%s\n标准错误:\n%s\n", outStr, errStr)
    	if err != nil {
    		fmt.Println("执行出错:",err)
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.4 使用管道,多条命令组合

    // ps aux | grep redis
    func main() {
    	c1 := exec.Command("ps", "aux")  // 命令1
    	c2 := exec.Command("grep", "redis") // 命令2
    	c2.Stdin, _ = c1.StdoutPipe() // c1的输出,作为c2.输入
    	c2.Stdout = os.Stdout   // c2的输出到控制台上
    	_ = c2.Start()  // c2立即启动,不等结果返回
    	_ = c1.Run()  // c1阻塞直到命令执行完成
    	_ = c2.Wait()  //c2阻塞直到Cmd中的命令执行完成
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.5 设置程序级别的环境变量

    func main() {
    
    	os.Setenv("name", "lqz")
    	//cmd := exec.Command("echo", os.ExpandEnv("$name"))
    	cmd := exec.Command("echo", os.ExpandEnv("$name"))
    	out, err := cmd.CombinedOutput()
    	if err != nil {
    		fmt.Println("执行出错:",err)
    	}
    	fmt.Printf("%s", out)
    
    }
    
    //ExpandEnv根据当前环境变量的值来替换字符串中的${var}或者$var。如果引用变量没有定义,则用空字符串替换
    s := "hello $GOROOT"
    fmt.Println(os.ExpandEnv(s))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    Spring Security 的前后端分离项目的权限方案,从0到0.8
    POJ1062 , kuangbin专题 昂贵的聘礼
    Leetcode.4 寻找两个正序数组的中位数
    CAPL如何在底层模拟TCP Server端建立TCP连接
    python之Scrapy爬虫案例:豆瓣
    Kubernetes亲和性学习笔记
    QML:拖动曲线坐标点修改曲线
    深度学习Tensorflow: CUDA_ERROR_OUT_OF_MEMORY解决办法
    Vue3多介绍使用
    Spring MVC
  • 原文地址:https://blog.csdn.net/qq_55752792/article/details/126104871