網站首頁 編程語言 正文
阻塞方式(需要執行結果)
主要用于執行shell命令,并且返回shell的標準輸出
適用于執行普通非阻塞shell命令,且需要shell標準輸出的
//阻塞式的執行外部shell命令的函數,等待執行完畢并返回標準輸出 func exec_shell(s string) (string, error){ //函數返回一個*Cmd,用于使用給出的參數執行name指定的程序 cmd := exec.Command("/bin/bash", "-c", s) //讀取io.Writer類型的cmd.Stdout,再通過bytes.Buffer(緩沖byte類型的緩沖器)將byte類型轉化為string類型(out.String():這是bytes類型提供的接口) var out bytes.Buffer cmd.Stdout = &out //Run執行c包含的命令,并阻塞直到完成。 這里stdout被取出,cmd.Wait()無法正確獲取stdin,stdout,stderr,則阻塞在那了 err := cmd.Run() checkErr(err) return out.String(), err }
需要對shell標準輸出的逐行實時進行處理的
func execCommand(commandName string, params []string) bool { //函數返回一個*Cmd,用于使用給出的參數執行name指定的程序 cmd := exec.Command(commandName, params...) //顯示運行的命令 fmt.Println(cmd.Args) //StdoutPipe方法返回一個在命令Start后與命令標準輸出關聯的管道。Wait方法獲知命令結束后會關閉這個管道,一般不需要顯式的關閉該管道。 stdout, err := cmd.StdoutPipe() if err != nil { fmt.Println(err) return false } cmd.Start() //創建一個流來讀取管道內內容,這里邏輯是通過一行一行的讀取的 reader := bufio.NewReader(stdout) //實時循環讀取輸出流中的一行內容 for { line, err2 := reader.ReadString('\n') if err2 != nil || io.EOF == err2 { break } fmt.Println(line) } //阻塞直到該命令執行完成,該命令必須是被Start方法開始執行的 cmd.Wait() return true }
非阻塞方式(不需要執行結果)
通過shell調用自己的程序,并且程序是死循環,此時無法獲取返回結果(否則程序會一直阻塞直至調用的 程序結束)
適用于調用自己寫的程序(服務器死循環,且不需要返回結果的)
//不需要執行命令的結果與成功與否,執行命令馬上就返回 func exec_shell_no_result(command string) { //處理啟動參數,通過空格分離 如:setsid /home/luojing/gotest/src/test_main/iwatch/test/while_little & command_name_and_args := strings.FieldsFunc(command, splite_command) //開始執行c包含的命令,但并不會等待該命令完成即返回 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出的子進程執行的結果,和cmd.Start()配合使用[不等待回收資源,會導致fork出執行shell命令的子進程變為僵尸進程] err = cmd.Wait() if err != nil { fmt.Printf("%v: Command finished with error: %v\n", get_time(), err) } return }
/錯誤處理函數 func checkErr(err error) { if err != nil { fmt.Println(err) panic(err) } }
引用部分文檔
func (*Cmd) Run func (c *Cmd) Run() error
Run執行c包含的命令,并阻塞直到完成。
如果命令成功執行,stdin、stdout、stderr的轉交沒有問題,并且返回狀態碼為0,方法的返回值為nil;如果命令沒有執行或者執行失敗,會返回*ExitError類型的錯誤;否則返回的error可能是表示I/O問題。
func (*Cmd) Start func (c *Cmd) Start() error
Start開始執行c包含的命令,但并不會等待該命令完成即返回。Wait方法會返回命令的返回狀態碼并在命令返回后釋放相關的資源。
func (*Cmd) Wait func (c *Cmd) Wait() error
Wait會阻塞直到該命令執行完成,該命令必須是被Start方法開始執行的。
如果命令成功執行,stdin、stdout、stderr的轉交沒有問題,并且返回狀態碼為0,方法的返回值為nil;如果命令沒有執行或者執行失敗,會返回*ExitError類型的錯誤;否則返回的error可能是表示I/O問題。Wait方法會在命令返回后釋放相關的資源。
func (*Cmd) Output func (c *Cmd) Output() ([]byte, error)
執行命令并返回標準輸出的切片。
func (*Cmd) StderrPipe func (c *Cmd) StderrPipe() (io.ReadCloser, error)
StderrPipe方法返回一個在命令Start后與命令標準錯誤輸出關聯的管道。Wait方法獲知命令結束后會關閉這個管道,一般不需要顯式的關閉該管道。但是在從管道讀取完全部數據之前調用Wait是錯誤的;同樣使用StderrPipe方法時調用Run函數也是錯誤的。
原文鏈接:https://blog.csdn.net/qq_36874881/article/details/78234005
相關推薦
- 2022-09-30 oracle表空間不足ORA-01653的問題:?unable?to?extend?table_or
- 2022-04-10 用python實現讀取xlsx表格操作_python
- 2022-08-11 GoFrame框架數據校驗之校驗結果Error接口對象_Golang
- 2023-01-05 Python?range函數之生成器函數的示例_python
- 2022-01-05 解決:啟動Redis報錯:`Could not create server TCP listenin
- 2022-03-14 easypoi導入校驗跳過空行_EasyPoi導入驗證功能
- 2023-05-12 Oracle中實現刪除重復數據只保留一條_oracle
- 2022-07-19 Python數據分析?Pandas?Series對象操作_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支