可能有人在问在什么情况下使用到这项技能,当你需要去调用本地脚本完成相关操作时,或者需要通过shell命令去获取系统相关信息时,便需要使用到这项技能。
当你在命令里面执行输出命令时:
echo 123;
我们可以在go语言中这样去调用:
//只是执行,不需要结果
func OnlyRun() {
var(
cmd *exec.Cmd
err error
)
cmd = exec.Command("bash", "-c", "echo 123")
err = cmd.Run()
fmt.Println(err)
}
执行结果:
<nil>
有时你可能需要执行一个命令拿到执行结果,比如让他帮我计算 1+1=?,你可能会这样执行:
echo `expr 1 + 1`;
我们在go语言中可以这样玩:
//需要获取执行结果
func GetRunValue() {
var(
cmd *exec.Cmd
err error
output []byte
)
cmd = exec.Command("bash","-c","echo `expr 1 + 1`;")
if output, err = cmd.CombinedOutput(); err != nil {
fmt.Println(err)
return
}
fmt.Println(string(output))
}
执行结果是:
2
这也算刚需吧,如果一个程序执行时卡死了,我们得把它kill掉吧,这我们就要需要使用到go语言中的goroutine去执行了。
我们模拟的使用场景是这样的: 我们先让程序睡眠3秒,来模拟这个程序在一直在执行,3秒后输出 hello
,在执行到第1秒时我们把它杀掉。
我的shell脚本是这样的:
sleep 3;echo hello;
我们go语言中是这样玩的:
//执行完发挥的数据结构
type result struct {
err error
output []byte
}
//能够杀死的进程
func CanKillRun() {
var(
cmd *exec.Cmd
ctx context.Context
cancelFunc context.CancelFunc
resultChan chan *result
res *result
)
//创建一个通道用户协程交换数据
resultChan = make(chan *result, 1000)
//拿到这个上下文的取消方法
ctx, cancelFunc = context.WithCancel(context.TODO())
//起一个goroutine 可以理解是子进程去处理
go func() {
var (
output []byte
err error
)
cmd = exec.CommandContext(ctx,"bash", "-c","sleep 3;echo hello;")
//执行任务,捕捉输出
output, err = cmd.CombinedOutput()
//把任务执行结果输出给main协程
resultChan <- &result{
err:err,
output:output,
}
}()
//1s 后我们就把他杀死
//继续往下走
time.Sleep(1 * time.Second)
//取消上下文
cancelFunc()
//读取通道里面的数据
res = <- resultChan
//打印结果
fmt.Println(res.err, string(res.output))
}
我们的执行结果是:
signal: killed
到这里咱们就结束了,如果有啥疑问,可以给我留言。