• go执行命令并获取命令输出简要示例


    背景:

    不管使用哪种开发语言,我们在项目中总会面临一些需要再执行一些命令获取信息的场景,java提供了Runtime.getRuntime().exec, go语言也提供类似的功能 exec.Command。 这些执行都可以配置输入,并捕获输出信息。

    代码:

    代码地址

    package main
    
    import (
    	"bytes"
    	"fmt"
    	"os"
    	"os/exec"
    	"strings"
    )
    
    func main() {
    	fmt.Println("output to std1, cmd can run normally")
    	printToStdNormal()
    
    	fmt.Println("output to std2, cmd can't run normally for the cmd args is not right")
    	printToStdError1()
    
    	fmt.Println("output to std3, cmd can't run normally for the cmd dir does not exist")
    	printToStdError2()
    
    	fmt.Println("output to std2")
    	printToStd2()
    
    	fmt.Println("read from std")
    	readFromStd()
    
    	fmt.Println("run with multi args")
    	execWithMultiArgs()
    
    	fmt.Println("主函数执行完毕")
    }
    
    func printToStdNormal() {
    	//设置需要执行的命令
    	cmd := exec.Command("ls", "-sh")
    	//将命令的输出和错误与标准的os.Stdout关联
    	cmd.Stdout = os.Stdout
    	cmd.Stderr = os.Stderr
    
    	//设置该命令执行的上下文目录信息
    	// 不设置dir时, dir默认值为当前程序启动的位置
    	cmd.Dir = "/"
    
    	err := cmd.Run()
    	if err != nil {
    		fmt.Printf("failed to call cmd.Run(): %v\n", err)
    	}
    	fmt.Println()
    }
    
    func printToStdError1() {
    	cmd := exec.Command("ls", "aaaa-sh")
    	cmd.Stdout = os.Stdout
    	cmd.Stderr = os.Stderr
    	cmd.Dir = "/"
    	err := cmd.Run()
    	if err != nil {
    		//错误信息输出该cmd的参数
    		fmt.Printf("failed to call cmd.Run() with args:%v,  err:%v\n", cmd.Args, err)
    	}
    	fmt.Println()
    }
    
    func printToStdError2() {
    	cmd := exec.Command("ls", "-sh")
    	cmd.Stdout = os.Stdout
    	cmd.Stderr = os.Stderr
    	cmd.Dir = "/not-exist"
    	err := cmd.Run()
    	if err != nil {
    		//错误信息输出该cmd的执行的目录
    		fmt.Printf("failed to call cmd.Run() with args:%v,  err:%v\n", cmd.Dir, err)
    	}
    	fmt.Println()
    }
    
    func printToStd2() {
    	//Output runs the command and returns its standard output
    	arg1 := os.ExpandEnv("${MY_ENV_VAR}")
    	// 目前读取动态自定义的环境变量有问题,通过os.ExpandEnv读取os已有的的环境环境变量没问题
    	//或者可以先通过os.Setenv("MY_ENV_VAR", "some_value1"), 然后os.ExpandEnv
    	cmd := exec.Command("echo", arg1)
    	cmd.Env = os.Environ()
    	cmd.Env = append(cmd.Env, "MY_ENV_VAR=some_value")
    
    	out, err := cmd.Output()
    	if err != nil {
    		fmt.Printf("failed to call cmd.Run() with args:%v, err:%v\n", cmd.Dir, err)
    		return
    	}
    
    	fmt.Printf("cmd '%s' executed in dir '%s' (命令执行的默认目录), env:%s, out:'%s'\n",
    		cmd.Args, cmd.Dir, cmd.Env, string(out))
    }
    
    func readFromStd() {
    	// tr - translate or delete characters
    	cmd := exec.Command("tr", "a-z", "A-Z")
    
    	//设置执行命令的input信息
    	cmd.Stdin = strings.NewReader("and old falcon")
    
    	var out bytes.Buffer
    	cmd.Stdout = &out
    
    	err := cmd.Run()
    
    	if err != nil {
    		fmt.Printf("failed to call cmd.Run() with args:%v, err:%v\n", cmd.Args, err)
    	}
    
    	fmt.Printf("translated phrase: %q\n\n", out.String())
    }
    func execWithMultiArgs() {
    	prg := "echo"
    
    	arg1 := "there"
    	arg2 := "are three"
    	arg3 := os.ExpandEnv("${JAVA_HOME}")
    
    	cmd := exec.Command(prg, arg1, arg2, arg3)
    	stdout, err := cmd.Output()
    
    	if err != nil {
    		fmt.Println(err.Error())
    		return
    	}
    
    	fmt.Printf("cmd '%s' executed in dir '%s' (命令执行的默认目录), env:%s, out:%s\n",
    		cmd.Args, cmd.Dir, cmd.Env, string(stdout))
    }
    
    • 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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131

    执行效果:

    output to std1, cmd can run normally
    total 10
     0 AppleInternal         0 Volumes               0 etc                               0 usr
     0 Applications          0 bin                   0 home                           0 var
     0 Library               0 coredata              0 opt                   
     0 System                0 cores                 0 sbin
     0 Users                10 dev                   0 tmp
    
    output to std2, cmd can't run normally for the cmd args is not right
    ls: aaaa-sh: No such file or directory (**这一句来自标准错误输出**)
    failed to call cmd.Run() with args:[ls aaaa-sh],  err:exit status 1
    
    output to std3, cmd can't run normally for the cmd dir does not exist
    failed to call cmd.Run() with args:/not-exist,  err:chdir /not-exist: no such file or directory
    
    output to std2
    cmd '[echo ]' executed in dir '' (命 令 执 行 的 默 认 目 录 ), env:[ALACRITTY_WINDOW_ID=0 
    ...此处省略部分内容
     HOME=/Users/ericyang  USER=ericyang WINDOWID=0 XPC_FLAGS=0x0 XPC_SERVICE_NAME=0 __CFBundleIdentifier=Fleet.app __CF_USER_TEXT_ENCODING=0x1F5:0x19:0x34 _=/usr/local/go/bin/go MY_ENV_VAR=some_value], out:'
    '
    read from std
    translated phrase: "AND OLD FALCON"
    
    run with multi args
    cmd '[echo there are three /Users/ericyang/.sdkman/candidates/java/current]' executed in dir '' (命 令 执 行 的 默 认 目 录 ), env:[], out:there are three /Users/ericyang/.sdkman/candidates/java/current
    
    主 函 数 执 行 完 毕 
    
    • 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
    • 27
  • 相关阅读:
    ESB(企业服务总线)
    代码随想录1.5——数组:35搜索插入位置、34在排序数组中查找元素的第一个和最后一个位置、26.删除排序数组中的重复项、283移动零
    记录vue开发实例
    操作系统——cpu、内存、缓存介绍
    [数据结构]二叉树的链式结构
    RN开发搬砖经验之-如何处理FlashList组件加载后调用scrollToIndex没有滚动指定位置
    AI网络爬虫:对网页指定区域批量截图
    用云机器/虚拟机架设方舟游戏?
    推荐算法详解
    【踩坑专栏】 Could not write JSON: No serializer found for class
  • 原文地址:https://blog.csdn.net/russle/article/details/133202756