go調(diào)用shell命令兩種方式實(shí)現(xiàn)(有無返回值)
阻塞方式(需要執(zhí)行結(jié)果)
主要用于執(zhí)行shell命令,并且返回shell的標(biāo)準(zhǔn)輸出
適用于執(zhí)行普通非阻塞shell命令,且需要shell標(biāo)準(zhǔn)輸出的
//阻塞式的執(zhí)行外部shell命令的函數(shù),等待執(zhí)行完畢并返回標(biāo)準(zhǔn)輸出 func exec_shell(s string) (string, error){ //函數(shù)返回一個(gè)*Cmd,用于使用給出的參數(shù)執(zhí)行name指定的程序 cmd := exec.Command("/bin/bash", "-c", s) //讀取io.Writer類型的cmd.Stdout,再通過bytes.Buffer(緩沖byte類型的緩沖器)將byte類型轉(zhuǎn)化為string類型(out.String():這是bytes類型提供的接口) var out bytes.Buffer cmd.Stdout = &out //Run執(zhí)行c包含的命令,并阻塞直到完成。 這里stdout被取出,cmd.Wait()無法正確獲取stdin,stdout,stderr,則阻塞在那了 err := cmd.Run() checkErr(err) return out.String(), err }
需要對(duì)shell標(biāo)準(zhǔn)輸出的逐行實(shí)時(shí)進(jìn)行處理的
func execCommand(commandName string, params []string) bool { //函數(shù)返回一個(gè)*Cmd,用于使用給出的參數(shù)執(zhí)行name指定的程序 cmd := exec.Command(commandName, params...) //顯示運(yùn)行的命令 fmt.Println(cmd.Args) //StdoutPipe方法返回一個(gè)在命令Start后與命令標(biāo)準(zhǔn)輸出關(guān)聯(lián)的管道。Wait方法獲知命令結(jié)束后會(huì)關(guān)閉這個(gè)管道,一般不需要顯式的關(guān)閉該管道。 stdout, err := cmd.StdoutPipe() if err != nil { fmt.Println(err) return false } cmd.Start() //創(chuàng)建一個(gè)流來讀取管道內(nèi)內(nèi)容,這里邏輯是通過一行一行的讀取的 reader := bufio.NewReader(stdout) //實(shí)時(shí)循環(huán)讀取輸出流中的一行內(nèi)容 for { line, err2 := reader.ReadString('\n') if err2 != nil || io.EOF == err2 { break } fmt.Println(line) } //阻塞直到該命令執(zhí)行完成,該命令必須是被Start方法開始執(zhí)行的 cmd.Wait() return true }
非阻塞方式(不需要執(zhí)行結(jié)果)
通過shell調(diào)用自己的程序,并且程序是死循環(huán),此時(shí)無法獲取返回結(jié)果(否則程序會(huì)一直阻塞直至調(diào)用的 程序結(jié)束)
適用于調(diào)用自己寫的程序(服務(wù)器死循環(huán),且不需要返回結(jié)果的)
//不需要執(zhí)行命令的結(jié)果與成功與否,執(zhí)行命令馬上就返回 func exec_shell_no_result(command string) { //處理啟動(dòng)參數(shù),通過空格分離 如:setsid /home/luojing/gotest/src/test_main/iwatch/test/while_little & command_name_and_args := strings.FieldsFunc(command, splite_command) //開始執(zhí)行c包含的命令,但并不會(huì)等待該命令完成即返回 cmd.Start() if err != nil { fmt.Printf("%v: exec command:%v error:%v\n", get_time(), command, err) } fmt.Printf("Waiting for command:%v to finish...\n", command) //阻塞等待fork出的子進(jìn)程執(zhí)行的結(jié)果,和cmd.Start()配合使用[不等待回收資源,會(huì)導(dǎo)致fork出執(zhí)行shell命令的子進(jìn)程變?yōu)榻┦M(jìn)程] err = cmd.Wait() if err != nil { fmt.Printf("%v: Command finished with error: %v\n", get_time(), err) } return }
/錯(cuò)誤處理函數(shù) func checkErr(err error) { if err != nil { fmt.Println(err) panic(err) } }
引用部分文檔
func (*Cmd) Run func (c *Cmd) Run() error
Run執(zhí)行c包含的命令,并阻塞直到完成。
如果命令成功執(zhí)行,stdin、stdout、stderr的轉(zhuǎn)交沒有問題,并且返回狀態(tài)碼為0,方法的返回值為nil;如果命令沒有執(zhí)行或者執(zhí)行失敗,會(huì)返回*ExitError類型的錯(cuò)誤;否則返回的error可能是表示I/O問題。
func (*Cmd) Start func (c *Cmd) Start() error
Start開始執(zhí)行c包含的命令,但并不會(huì)等待該命令完成即返回。Wait方法會(huì)返回命令的返回狀態(tài)碼并在命令返回后釋放相關(guān)的資源。
func (*Cmd) Wait func (c *Cmd) Wait() error
Wait會(huì)阻塞直到該命令執(zhí)行完成,該命令必須是被Start方法開始執(zhí)行的。
如果命令成功執(zhí)行,stdin、stdout、stderr的轉(zhuǎn)交沒有問題,并且返回狀態(tài)碼為0,方法的返回值為nil;如果命令沒有執(zhí)行或者執(zhí)行失敗,會(huì)返回*ExitError類型的錯(cuò)誤;否則返回的error可能是表示I/O問題。Wait方法會(huì)在命令返回后釋放相關(guān)的資源。
func (*Cmd) Output func (c *Cmd) Output() ([]byte, error)
執(zhí)行命令并返回標(biāo)準(zhǔn)輸出的切片。
func (*Cmd) StderrPipe func (c *Cmd) StderrPipe() (io.ReadCloser, error)
StderrPipe方法返回一個(gè)在命令Start后與命令標(biāo)準(zhǔn)錯(cuò)誤輸出關(guān)聯(lián)的管道。Wait方法獲知命令結(jié)束后會(huì)關(guān)閉這個(gè)管道,一般不需要顯式的關(guān)閉該管道。但是在從管道讀取完全部數(shù)據(jù)之前調(diào)用Wait是錯(cuò)誤的;同樣使用StderrPipe方法時(shí)調(diào)用Run函數(shù)也是錯(cuò)誤的。
到此這篇關(guān)于go調(diào)用shell命令兩種方式實(shí)現(xiàn)(有無返回值)的文章就介紹到這了,更多相關(guān)go調(diào)用shell內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang實(shí)現(xiàn)程序優(yōu)雅退出的方法詳解
項(xiàng)目開發(fā)過程中,隨著需求的迭代,代碼的發(fā)布會(huì)頻繁進(jìn)行,在發(fā)布過程中,Golang如何讓程序做到優(yōu)雅的退出?本文就來詳細(xì)為大家講講2022-06-06一文深入探索Go語言中的循環(huán)結(jié)構(gòu)
在編程中,循環(huán)結(jié)構(gòu)扮演著重要的角色,它使我們能夠有效地重復(fù)執(zhí)行特定的代碼塊,以實(shí)現(xiàn)各種任務(wù)和邏輯,在Go語言中,for 是 Go 中唯一的循環(huán)結(jié)構(gòu),本文將深入探討Go語言中的for循環(huán)類型以及它們的用法2023-08-08Go語言操作mysql數(shù)據(jù)庫簡(jiǎn)單例子
這篇文章主要介紹了Go語言操作mysql數(shù)據(jù)庫簡(jiǎn)單例子,本文包含插入數(shù)據(jù)和查詢代碼實(shí)例,需要的朋友可以參考下2014-10-10Go習(xí)慣用法(多值賦值短變量聲明賦值簡(jiǎn)寫模式)基礎(chǔ)實(shí)例
本文為大家介紹了Go習(xí)慣用法(多值賦值,短變量聲明和賦值,簡(jiǎn)寫模式、多值返回函數(shù)、comma,ok 表達(dá)式、傳值規(guī)則)的基礎(chǔ)實(shí)例,幫大家鞏固扎實(shí)Go語言基礎(chǔ)2024-01-01Go并發(fā)同步Mutex典型易錯(cuò)使用場(chǎng)景
這篇文章主要為大家介紹了Go并發(fā)同步Mutex典型易錯(cuò)使用場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08gin自定義中間件解決requestBody不可重讀(請(qǐng)求體取值)
這篇文章主要介紹了gin自定義中間件解決requestBody不可重讀,確保控制器能夠獲取請(qǐng)求體值,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10