新聞中心
go語言用來執(zhí)行一個系統(tǒng)的命令相對python來說還是有點復雜的,執(zhí)行命令是一個非常常見的需求,如調用一個系統(tǒng)命令,啟一個exe等,這里分為幾種情況,之后統(tǒng)一總結一下。

來賓網(wǎng)站建設公司創(chuàng)新互聯(lián),來賓網(wǎng)站設計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為來賓近千家提供企業(yè)網(wǎng)站建設服務。企業(yè)網(wǎng)站搭建\外貿網(wǎng)站制作要多少錢,請找那個售后服務好的來賓做網(wǎng)站的公司定做!
- 只執(zhí)行命令,不要輸出結果
- 執(zhí)行命令并且要獲取到輸出結果
- 阻塞和異步的執(zhí)行
以下以ping www.baidu.com 為例依次執(zhí)行一下各種命令,主要使用標準庫中的os/exec。
在執(zhí)行命令的時候,我們主要使用的是os/exec包主的Cmd結構體方法,Cmd的結構體定義如下 Cmd結構體定義[1]。
主要的參數(shù)有
- Path string
- // Args保管命令的參數(shù),包括命令名作為第一個參數(shù);如果為空切片或者nil,相當于無參數(shù)命令。
- //
- // 典型用法下,Path和Args都應被Command函數(shù)設定。
- Args []string
- // Env指定進程的環(huán)境,如為nil,則是在當前進程的環(huán)境下執(zhí)行。
- Stdin io.Reader
- // Stdout和Stderr指定進程的標準輸出和標準錯誤輸出。
- //
- // 如果任一個為nil,Run方法會將對應的文件描述符關聯(lián)到空設備(os.DevNull)
- //
- // 如果兩個字段相同,同一時間最多有一個線程可以寫入。
- Stdout io.Writer
- Stderr io.Writer
但是我們一般不直接構造Cmd結構體,而是通過exec.Command() 函數(shù)返回一個Cmd結構體指針 如 exec.Command("ping","www.baidu.com") ping為命令,"www.baidu.com" 為參數(shù),在得到*Cmd以后再使用結構體方法Run,Start等方法來真正的執(zhí)行命令。
只執(zhí)行命令,不要輸出結果這里的輸出結果只是表明命令執(zhí)行了,但是它具體的輸出我們不關心,在這種其實用的挺多的,我們只是想執(zhí)行命令,在python里我們可以使用os.system() 函數(shù)來執(zhí)行,當然這個是阻塞的執(zhí)行。
- >>> import os
- >>> r = os.system("ping www.baidu.com")
- 正在 Ping www.a.shifen.com [39.156.66.18] 具有 32 字節(jié)的數(shù)據(jù):
- 來自 39.156.66.18 的回復: 字節(jié)=32 時間=6ms TTL=54
- 來自 39.156.66.18 的回復: 字節(jié)=32 時間=28ms TTL=54
- 來自 39.156.66.18 的回復: 字節(jié)=32 時間=6ms TTL=54
- 來自 39.156.66.18 的回復: 字節(jié)=32 時間=7ms TTL=54
- 39.156.66.18 的 Ping 統(tǒng)計信息:
- 數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
- 往返行程的估計時間(以毫秒為單位):
- 最短 = 6ms,最長 = 28ms,平均 = 11ms
- >>> r
- 0
這里的r只是獲取了該命令的執(zhí)行結果,是0表示沒有錯誤,但是執(zhí)行命令的輸出如 正在 Ping www.a.shifen.com..... 我們并不關心。
執(zhí)行命令可以使用Run() 或者Start() 方法,Run是阻塞的執(zhí)行,Start() 是非阻塞的執(zhí)行。
程序什么也沒有輸出,但是停頓的一段時間后才退出。如果換成command.Start() 則程序運行起來以后馬上就停止了。
如果想要獲取到像python 那種 os.system的執(zhí)行結果,其實這里的結果應該是ExitError,程序的退出碼,應該怎么操作呢?這里exec包里有一個專門的結構體ExitError,使用它的一些方法可以獲取到ExitCode,但是想要獲取到ExitCode得到得到命令結束,也就是要阻塞的運行,上面使用Run() 方法可以阻塞等待執(zhí)行結果,使用Start()方法以后,也可以使用Wait()方法來等待執(zhí)行結束。
通過
- command.ProcessState.Sys().(syscall.WaitStatus).ExitCode
來獲取到命令執(zhí)行的退出碼。
執(zhí)行命令并且要獲取到輸出結果這里的輸出結果是命令行的標準輸出或者錯誤輸出,也就是stdout或者stderr,通過bytes.Buffer來存儲。
這里得到的中文輸出有亂碼:
這個我查了一下一般都是說是設置一下控制臺輸出chcp或者使用:
- golang.org/x/text/encoding/simplifiedchinese
這個包進行轉換,我不想使用,這個以后找到方法再說吧。
命令行的輸入有時候進入命令行會等待用戶的交互,如輸入nslookup。
執(zhí)行不在環(huán)境變量里的命令像上面這個ping 命令,由于在windows 或者linux中,這個命令是在環(huán)境變量里,但是像windows中的copy 命令,它是不在環(huán)境變量里,正常情況下你可以在cmd中使用copy 命令,但是如果在go 語言中如果直接像上面那樣使用是不行的。 例如使用上面的代碼,替換一下copy 命令。
得到的輸出結果為:
- run error :exec: "copy": executable file not found in %PATH%
應該使用cmd", "/C" copy命令:
本文標題:Go語言中執(zhí)行命令的幾種方式
URL鏈接:http://www.fisionsoft.com.cn/article/dpdpspc.html


咨詢
建站咨詢
