Golang os/exec 使用方法(筆記)
Toby
Toby

此筆記是一個簡單純粹的快速參考目錄,方便我(或是你?)在開發時使用 os/exec 之用。如需要詳細的教學或 API 資料,請直接參閱

https://golang.org/pkg/os/exec/

此文中有部分例子參考自:
https://colobu.com/2017/06/19/advanced-command-execution-in-Go-with-os-exec/

執行指令並回傳結果

func main() {
	cmd := exec.Command("ls", "-lah")
	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Fatalf("cmd.Run() failed with %s\n", err)
	}
	fmt.Printf("combined out:\n%s\n", string(out))
}

加入額外的環境參數再執行指令

cmd := exec.Command("programToExecute")
additionalEnv := "FOO=bar"
newEnv := append(os.Environ(), additionalEnv))
cmd.Env = newEnv
out, err := cmd.CombinedOutput()
if err != nil {
	log.Fatalf("cmd.Run() failed with %s\n", err)
}
fmt.Printf("%s", out)

指定 CWD 並執行指令

cmd:= exec.Command("git", "log")
cmd.Dir = "your/intended/working/directory"
out, err := cmd.Output()

注意:使用上術的方式時請確保相關的指令存在於 ENV 參數內(或 Windows 的 %PATH%),如果不是,請使用 binary 的 Absolute Path,例如:

abspath, _ := filepath.Abs("./mybinary")
cmd:= exec.Command(abspath, "log")
cmd.Dir = "your/intended/working/directory"
out, err := cmd.Output()

在 Linux 下使用 os/exec + Pipe 或 Bash 運算式

rcmd := `iw dev | awk '$1=="Interface"{print $2}'`
cmd := exec.Command("bash", "-c", rcmd)
out, err := cmd.CombinedOutput()
if err != nil {
	log.Println(err.Error())
}
log.Println(string(out))

在 Windows 下使用 os/exec + Batch 運算式

cmd := exec.Command("cmd", "/c", "ffmpeg -i myfile.mp4 myfile.mp3 && del myfile.mp4")
out, err := cmd.CombinedOutput()
if err != nil {
	log.Println(err.Error())
}
log.Println(string(out))

使用 String Slice 為指令傳進 os/exec

args := []string{"hello", "world"}
cmd := exec.Command("echo", args...)
out, err := cmd.Output()
if err != nil {
    fmt.Println(err)
}
fmt.Println(string(out))

解決 Windows CMD 在 os/exec 時會出現本地語言的問題

在執行相關指令前先執行 chcp 65001 ,例子如下:

cmd := exec.Command("cmd", "/c", "chcp 65001 && netsh WLAN show drivers")
out, err := cmd.CombinedOutput()
if err != nil {
	log.Println(err.Error())
}
log.Println(string(out))

使用此方法得出的 output string 請記得把回傳的首行(chcp 的回傳結果)刪除掉再進行其他處理和讀取。