Golang地表最狂(一)—— 標準庫os/exec學習

偽粉表示stepping stone是真的燃
“來到舞臺接受到的目光 怎麼都不一樣 面對親戚朋友父母親的所有抵抗 我努力獨立成長 守護著自己堅強 但為了媽媽每日翹楚以盼長大 才對 他們劍拔弩張 我是雙截棍柔中帶剛 不用去少林武當 Not afraid 地表最狂 舉世無雙 撐這束追光 不怕艱險的 別人不知道的力量 不知道的力量 各霸一方 遺忘你鎩羽而歸的地方 你會前進 步履艱辛 但終究得要習慣投降 想當然爾 盜鈴掩耳 是你最大的致命傷 我按兵不動 有恃無恐 沉默的醞釀 純粹出於我禮貌的開場 神華內斂才能以柔克剛 試探性衡量 暗箭難防 自尊受傷 成王敗退 沒什麼兩樣 我運籌帷幄 仰望夕陽 你放棄抵抗 低頭離場 但不用放在心上 是因為我們是地表最狂”---聽到mdr-1abt燃燒的聲音,真的進入一個自己的世界,碼字也會變的飛快。。。。。
第一次寫技術部落格(裝b),不不不第一次在網上記筆記。。。嗯嗯,為什麼想到記筆記,因為覺得今天看了導師給的學習計劃,我感覺自己好像對學習Golang有了些許的激情,所以懶得去配的環境秒配,懶得裝的goland秒裝(感謝今天幸哥給的破解檔案讓老夫能夠安心的擼程式碼)。
所以看了第一週的學習計劃,嗯,大概就是學習語言最基礎的那些東西了,什麼資料型別、常量等等,然後作業秒做,就剩一個最後的任務用——用標準庫os/exec查詢系統所有ip這個貌似很有挑戰性的東西??貌似我這一週都可以好好學習這個標準庫??
步入正題,exec包執行外部命令,它將os.StartProcess進行包裝使得它更容易對映到stdin和stdout,並且利用pipe連線I/o。
1.func LookPath(file string) (string, error) //LookPath在環境變數中查詢可執行二進位制檔案,如果file中包含一個斜槓,則直接根據絕對路徑或者相對本目錄的相對路徑去查詢。
func main() { f, err := exec.LookPath("D:/GOPATH/src/myGo/exec.go") if err != nil { fmt.Println(err)//輸出錯誤 } fmt.Println(f) //輸出路徑 }
2.type Cmd //表示一個正在準備或者正在執行的外部命令
type Cmd struct { Path string //執行命令的路徑,絕對路徑或者相對路徑 Args []string // 命令引數 Env []string //程序環境,如果環境為空,則使用當前程序的環境 Dir string //指定command的工作目錄,如果dir為空,則comman在呼叫程序所在當前目錄中執行 Stdin io.Reader //標準輸入,如果stdin是nil的話,程序從null device中讀取(os.DevNull),stdin也可以時一個檔案,否則的話則在執行過程中再開一個goroutine去讀取標準輸入 Stdout io.Writer //標準輸出 Stderr io.Writer //錯誤輸出,如果這兩個(Stdout和Stderr)為空的話,則command執行時將響應的檔案描述符連線到os.DevNull ExtraFiles []*os.File SysProcAttr *syscall.SysProcAttr Process *os.Process //Process是底層程序,只啟動一次 ProcessState *os.ProcessState //ProcessState包含一個退出程序的資訊,當程序呼叫Wait或者Run時便會產生該資訊. }
3.func Command(name string, arg ...string) *Cmd //command返回cmd結構來執行帶有相關引數的命令,它僅僅設定cmd結構中的Path和Args引數,如果name引數中不包含路徑分隔符,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" }
4.func (c *Cmd) CombinedOutput() ([]byte, error) //執行命令,並返回標準輸出和標準錯誤
func main() { cmd := exec.Command("ls") //檢視當前目錄下檔案 out, err := cmd.CombinedOutput() if err != nil { fmt.Println(err) } fmt.Println(string(out)) }
這裡遇到一個ls:%l is not a valid Win32 application.的問題,看來可以請教導師一波。。。
5.func (c *Cmd) Output() ([]byte, error) //執行命令並返回其標準輸出
6.func main() { cmd := exec.Command("ls") ///檢視當前目錄下檔案 out, err := cmd.Output() if err != nil { fmt.Println(err) } fmt.Println(string(out))//媽蛋,還是上面那個報錯 }
注意:Output()和CombinedOutput()不能夠同時使用,因為command的標準輸出只能有一個,同時使用的話便會定義了兩個,便會報錯
6.func (c *Cmd) Run() error //開始指定命令並且等待他執行結束,如果命令能夠成功執行完畢,則返回nil,否則的話邊會產生錯誤
7.func (c *Cmd) Start() error //使某個命令開始執行,但是並不等到他執行結束,這點和Run命令有區別.然後使用Wait方法等待命令執行完畢並且釋放響應的資源
func main() { cmd := exec.Command("ls") cmd.Stdout = os.Stdout // cmd.Run() fmt.Println(cmd.Start()) //exec: already started }
注:一個command只能使用Start()或者Run()中的一個啟動命令,不能兩個同時使用.
8.func (c *Cmd) StderrPipe() (io.ReadCloser, error) //StderrPipe返回一個pipe,這個管道連線到command的標準錯誤,當command命令退出時,Wait將關閉這些pipe
9.func (c *Cmd) StdinPipe() (io.WriteCloser, error) //StdinPipe返回一個連線到command標準輸入的管道pipe
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 //終端標準輸出tmp.txt cmd.Start() }
10.func (c *Cmd) StdoutPipe() (io.ReadCloser, error) //StdoutPipe返回一個連線到command標準輸出的管道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命令檢視到的內容 }
11.func (c *Cmd) Wait() error //Wait等待command退出,他必須和Start一起使用,如果命令能夠順利執行完並順利退出則返回nil,否則的話便會返回error,其中Wait會是放掉所有與cmd命令相關的資源
type Error //Error返回科執行二進位制檔名字不能夠執行的原因的錯誤
12.func (e *Error) Error() string
type ExitError//一個command不能夠正常退出的error
最後那道題還是這樣解決的:

代賣

終端
最後的問題是中文亂碼,因為內網連不到GitHub,所以看來可以繼續下一個筆記了: "code.google.com/p/mahonia" mahonia包的使用。。。做事講順序,講話要押韻,裝完逼就跑真刺激。。。