Go语言执行第三方外部进程

字号+ 编辑: IT男在阿里 修订: 种花家 来源: 原创 2023-09-11 我要说两句(0)

Go语言如何像python那样触发shell指令的呢?

有时候项目需要实现一个类似shell脚本的功能,让开发项目自身程序类型以外的其他脚本程序(或者编译后程序)来根据情况执行,这个时候不会python怎么办?go语言可以帮助我们实现。先写一些linux下shell命令的例子:

package main

import(
    "fmt"
    "io/ioutil"
    "os/exec"
)

func main() {
	// 从一个简单的命令开始 这个命令不需要任何参数
	// 或者输入,仅仅向stdout输出一些信息,使用包里面的exec.Command
	dateCmd := exec.Command("date")

	// Output 是另一个运行命令时用来处理信息的函数,这个函数等待命令结束,然后收集命令输出,如果没有错误发生的话,
	// dateOut 将保存date的信息
	dateOut, err := dateCmd.Output()
	if err != nil {
		panic(err)
	}
	fmt.Println("> date")
	fmt.Println(string(dateOut))

	// 下面我们看一个需要从stdin输入数据的命令, 我们将数据输入传给外部进程stdin
	// 然后从它输出到stdout的运行结果收集信息
	grepCmd := exec.Command("grep", "hello")

	// 这里我们显式地获取input/output管道,启动进程,向进程写入数据,然后读取输出结果,最后等待进程结束
	grepIn, _ := grepCmd.StdinPipe()
	grepOut, _ := grepCmd.StdoutPipe()
	grepCmd.Start()
	grepIn.Write([]byte("hello grep\ngoodbye grep"))
	grepIn.Close()
	grepBytes, _ := ioutil.ReadAll(grepOut)
	grepCmd.Wait()

	// 在上面的例子中,我开门忽略了错误检测,但是你一样可以使用 if err!=nil 这种模式来进行处理,
	// 另外,我们仅仅收集了stdoutPipe 的结果,同时你也可以用一样的方法来收集StderrPipe的结果
	fmt.Println("> grep hello")
	fmt.Println(string(grepBytes))

	// 注意,在触发外部命令的时候,需要显式地提供命令和参数信息
	// 另外如果你想用一个命令行字符串触发一个完整的命令, 你可以使用bash的一个-c选项

	lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
	lsOut, err := lsCmd.Output()
	if err != nil {
		panic(err)
	}
	fmt.Println("> ls -a -l -h")
	fmt.Println(string(lsOut))
}

所触发的程序执行结果和我们直接执行这些程序的结果是一样的, 运行结果:

> date
Sat Dec 8 11:18:35 PDT 2017
> grep hello
hello grep
> ls -a -l -h
drwxr-xr-x  4 qinchao 136B Dec 3 10:10 .
drwxr-xr-x 91 qinchao 3.0K Dec 3 10:10 ..
-rw-r--r--  1 qinchao 138K Dec 3 10:10
spawning-processes.go

一些新手遇到比较复杂连续的shell命令, 上来可能就开心地写了以下的代码

	xxCmd := exec.Command("chmod -R 755 /root/sample")
	xxOut, err := xxCmd.Output()
	if err != nil {
		panic(err)
	}

发现会报错误no such file or directory

这里纠正一下, 你首先要传入bash执行路径作为第一个参数, 第二个参数传入bash的执行参数, 一般都是-c, 最后的第三个参数才是传shell指令。所以面对以上这种报错解决方式, 应该这样写:

// 加入/bin/bash和-c作为前两个参数
	xxCmd := exec.Command("/bin/bash", "-c", "chmod -R 777 /root/sample")
	xxOut, err := xxCmd.Output()
	if err != nil {
		panic(err)
	}


阅完此文,您的感想如何?
  • 有用

    1

  • 没用

    0

  • 开心

    0

  • 愤怒

    0

  • 可怜

    0

1.如文章侵犯了您的版权,请发邮件通知本站,该文章将在24小时内删除;
2.本站标注原创的文章,转发时烦请注明来源;
3.交流群: PHP+JS聊天群

相关课文
  • GO语言GORM如何更新字段

  • gorm如何创建记录与模型定义需要注意什么

  • gorm一般查询与高级查询

  • GORM时间戳跟踪及CURD(增删改查)

我要说说
网上宾友点评