• 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
  • 相关阅读:
    QT day1
    客服支持Chatbot提供即时回答,改善用户体验
    MySQL 使用触发器记录用户的操作日志
    深度神经网络 英语,深度神经网络英文
    HCIA证书能拿到的薪资高吗
    Programming abstractions in C阅读笔记:p144-p160
    java计算机毕业设计ssm信息科技知识交流学习平台
    数据结构——时间复杂度&空间复杂度
    java计算机毕业设计高校后勤保修系统MyBatis+系统+LW文档+源码+调试部署
    unexpected end of stream on
  • 原文地址:https://blog.csdn.net/russle/article/details/133202756