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(增刪改查)

我要說說
網上賓友點評