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.交流群: 2702237 13835667

相關課文
  • GO語言GORM如何更新字段

  • gorm如何創建記錄與模型定義需要注意什麽

  • gorm一般查詢與高級查詢

  • GORM時間戳跟蹤及CURD(增刪改查)

我要說說
網上賓友點評