我是 golang 的新手,嘗試過但沒有想到。我想執行一個 shell 命令,然后將錯誤(如果存在)作為通道或 stdoutput 作為通道回傳。
到目前為止,我已經這樣做了:
package main
import (
"bufio"
"io"
"os"
"os/exec"
)
type CommandRequest struct {
Command string
Args string
}
type CommandResponse struct {
StdOut chan string
StdErr chan string
}
func main() {
ExecuteCommand();
}
func ExecuteCommand() CommandResponse {
cmd := exec.Command("ping", "192.168.0.1")
_, err := cmd.Output()
var returnValue CommandResponse
if err != nil {
output := make(chan string)
go func() { output <- read(os.Stdout) }()
returnValue = CommandResponse{output, nil} //Reading from Stdin
}
return returnValue
}
func read(r io.Reader) <-chan string {
lines := make(chan string)
go func() {
defer close(lines)
scan := bufio.NewScanner(r)
for scan.Scan() {
lines <- scan.Text()
}
}()
return lines
}
操場鏈接https://play.golang.org/p/pJ2R6fzK8gR 我盡可能地減少錯誤,剩下的和我的作業區一樣
uj5u.com熱心網友回復:
有幾種方法可以讀取命令輸出。
一、輸出方式
這是最簡單的一種。直接從輸出中獲取
func main() {
out, _ := exec.Command("./ping", "192.168.0.1").Output()
fmt.Printf("Stdout: %s\n", string(out))
}
2. 將輸出重定向到 bytes.Buffer
func main() {
var stdout, stderr bytes.Buffer
cmd := exec.Command("./ping", "192.168.0.1")
cmd.Stdout = &stdout
cmd.Stderr = &stderr
_ := cmd.Run()
fmt.Printf("Stdout: %s\n", stdout.String())
fmt.Printf("Stderr: %s\n", stderr.String())
}
2. 帶通道的標準管
我們通常不會像在您的代碼中那樣回傳通道,因為它們用于保存和移動資料的用法與變數不同。我們將它們作為引數傳遞給函式,并從不同的行程(goroutines)讀取/寫入這些通道。
您可以使用 StdoutPipe() 方法從管道獲取輸出作為 io.Readcloser。然后用 bufio.Scanner 讀取。如您所見,我在這里使用了頻道。
func main() {
cmd := exec.Command("./ping", "192.168.0.1")
cmdReader, _ := cmd.StdoutPipe()
scanner := bufio.NewScanner(cmdReader)
out := make(chan string)
go reader(scanner, out)
done := make(chan bool)
go func() {
value := <-out
println(value)
done <- true
}()
_ = cmd.Run()
<-done
}
func reader(scanner *bufio.Scanner, out chan string) {
for scanner.Scan() {
out <- scanner.Text()
}
}
uj5u.com熱心網友回復:
通道是連接并發 goroutine 的管道。您可以將值從一個 goroutine 發送到通道,然后將這些值接收到另一個 goroutine 中。如果未使用緩沖通道,則發送和接收阻塞,直到另一端準備就緒。回傳頻道可能不是適當的頻道使用。
有兩個選項可以解決您的問題
選項 1:不使用通道,只是簡單地回傳 CommandResponse。
package main
import (
"fmt"
"os/exec"
)
type CommandRequest struct {
Command string
Args string
}
func main() {
cr := CommandRequest{"ls", "-la"}
fmt.Println(ExecuteCommand(cr))
}
func ExecuteCommand(cr CommandRequest) string{
cmd := exec.Command(cr.Command, cr.Args)
stdout, err := cmd.Output()
if err != nil {
return err.Error()
}
return string(stdout)
}
選項2:使用頻道但不回傳。創建一個通道并將其作為引數傳遞并在 main() 中保持阻塞接收。因此 ExecuteCommand() 可以執行 shell 命令并通過通道發送回傳狀態。
package main
import (
"fmt"
"os/exec"
)
type CommandRequest struct {
Command string
Args string
}
func main() {
cr := CommandRequest{"ls", "-la"}
retc := make(chan string)
go ExecuteCommand(cr, retc)
ret := <-retc
fmt.Println(ret)
}
func ExecuteCommand(cr CommandRequest, retc chan string) {
cmd := exec.Command(cr.Command, cr.Args)
stdout, err := cmd.Output()
if err != nil {
retc <- err.Error()
return
}
retc <- string(stdout)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/341827.html
上一篇:顯示并行運行的腳本的進度
