exec包執(zhí)行外部命令,它將os.StartProcess進行包裝使得它更容易映射到stdin和stdout,并且利用pipe連接i/o.
func LookPath(file string) (string, error) //LookPath在環(huán)境變量中查找科執(zhí)行二進制文件,如果file中包含一個斜杠,則直接根據(jù)絕對路徑或者相對本目錄的相對路徑去查找
- func main() {
- f, err := exec.LookPath("ls")
- if err != nil {
- fmt.Println(err)
- }
- fmt.Println(f) // /bin/ls
- }
type Cmd //表示一個正在準(zhǔn)備或者正在運行的外部命令
- type Cmd struct {
- Path string //運行命令的路徑,絕對路徑或者相對路徑
- Args []string // 命令參數(shù)
- Env []string //進程環(huán)境,如果環(huán)境為空,則使用當(dāng)前進程的環(huán)境
- Dir string //指定command的工作目錄,如果dir為空,則comman在調(diào)用進程所在當(dāng)前目錄中運行
- Stdin io.Reader //標(biāo)準(zhǔn)輸入,如果stdin是nil的話,進程從null device中讀取(os.DevNull),stdin也可以時一個文件,否則的話則在運行過程中再開一個goroutine去
- //讀取標(biāo)準(zhǔn)輸入
- Stdout io.Writer //標(biāo)準(zhǔn)輸出
- Stderr io.Writer //錯誤輸出,如果這兩個(Stdout和Stderr)為空的話,則command運行時將響應(yīng)的文件描述符連接到os.DevNull
- ExtraFiles []*os.File
- SysProcAttr *syscall.SysProcAttr
- Process *os.Process //Process是底層進程,只啟動一次
- ProcessState *os.ProcessState //ProcessState包含一個退出進程的信息,當(dāng)進程調(diào)用Wait或者Run時便會產(chǎn)生該信息.
- }
func Command(name string, arg ...string) *Cmd //command返回cmd結(jié)構(gòu)來執(zhí)行帶有相關(guān)參數(shù)的命令,它僅僅設(shè)定cmd結(jié)構(gòu)中的Path和Args參數(shù),如果name參數(shù)中不包含路徑分隔符,command使用LookPath來解決路徑問題,否則的話就直接使用name;Args直接跟在command命令之后,所以在Args中不許要添加命令.
- func main() {
- cmd := exec.Command("tr", "a-z", "A-Z")
- cmd.Stdin = strings.NewReader("some input")
- var out bytes.Buffer
- cmd.Stdout = &out
- err := cmd.Run()
- if err != nil {
- log.Fatal(err)
- }
- fmt.Printf("in all caps: %q\n", out.String()) //in all caps: "SOME INPUT"
- }
func (c *Cmd) CombinedOutput() ([]byte, error) //運行命令,并返回標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤
- func main() {
- cmd := exec.Command("ls") //查看當(dāng)前目錄下文件
- out, err := cmd.CombinedOutput()
- if err != nil {
- fmt.Println(err)
- }
- fmt.Println(string(out))
- }
func (c *Cmd) Output() ([]byte, error) //運行命令并返回其標(biāo)準(zhǔn)輸出
- func main() {
- cmd := exec.Command("ls") ///查看當(dāng)前目錄下文件
- out, err := cmd.Output()
- if err != nil {
- fmt.Println(err)
- }
- fmt.Println(string(out))
- }
注意:Output()和CombinedOutput()不能夠同時使用,因為command的標(biāo)準(zhǔn)輸出只能有一個,同時使用的話便會定義了兩個,便會報錯
func (c *Cmd) Run() error //開始指定命令并且等待他執(zhí)行結(jié)束,如果命令能夠成功執(zhí)行完畢,則返回nil,否則的話邊會產(chǎn)生錯誤
func (c *Cmd) Start() error //使某個命令開始執(zhí)行,但是并不等到他執(zhí)行結(jié)束,這點和Run命令有區(qū)別.然后使用Wait方法等待命令執(zhí)行完畢并且釋放響應(yīng)的資源
- func main() {
- cmd := exec.Command("ls")
- cmd.Stdout = os.Stdout //
- cmd.Run()
- fmt.Println(cmd.Start()) //exec: already started
- }
注:一個command只能使用Start()或者Run()中的一個啟動命令,不能兩個同時使用.
func (c *Cmd) StderrPipe() (io.ReadCloser, error) //StderrPipe返回一個pipe,這個管道連接到command的標(biāo)準(zhǔn)錯誤,當(dāng)command命令退出時,Wait將關(guān)閉這些pipe
func (c *Cmd) StdinPipe() (io.WriteCloser, error) //StdinPipe返回一個連接到command標(biāo)準(zhǔn)輸入的管道pipe
- package main
-
- import (
- "fmt"
- "os"
- "os/exec"
- )
-
- func main() {
- cmd := exec.Command("cat")
- stdin, err := cmd.StdinPipe()
- if err != nil {
- fmt.Println(err)
- }
- _, err = stdin.Write([]byte("tmp.txt"))
- if err != nil {
- fmt.Println(err)
- }
- stdin.Close()
- cmd.Stdout = os.Stdout //終端標(biāo)準(zhǔn)輸出tmp.txt
- cmd.Start()
- }
func (c *Cmd) StdoutPipe() (io.ReadCloser, error) //StdoutPipe返回一個連接到command標(biāo)準(zhǔn)輸出的管道pipe
- func main() {
- cmd := exec.Command("ls")
- stdout, err := cmd.StdoutPipe() //指向cmd命令的stdout
- cmd.Start()
- content, err := ioutil.ReadAll(stdout)
- if err != nil {
- fmt.Println(err)
- }
- fmt.Println(string(content)) //輸出ls命令查看到的內(nèi)容
- }
func (c *Cmd) Wait() error //Wait等待command退出,他必須和Start一起使用,如果命令能夠順利執(zhí)行完并順利退出則返回nil,否則的話便會返回error,其中Wait會是放掉所有與cmd命令相關(guān)的資源
type Error //Error返回科執(zhí)行二進制文件名字不能夠執(zhí)行的原因的錯誤
- type Error struct {
- Name string
- Err error
- }
func (e *Error) Error() string
type ExitError //一個command不能夠正常退出的error
- type ExitError struct {
- *os.ProcessState
- }
func (e *ExitError) Error() string