Golang执行shell命令并作为通道返回



我是第一次尝试,但没有进入我的脑海。我想执行一个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我尽我所能地减少错误和什么是相同的,我得到在我的工作空间以及

有两种方法可以从命令输出中读取。

1。输出方法

这是最简单的一个。直接从Output

中获取
func main() {
out, _ := exec.Command("./ping", "192.168.0.1").Output()
fmt.Printf("Stdout: %sn", string(out))
}

2。重定向输出到字节。缓冲

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: %sn", stdout.String())
fmt.Printf("Stderr: %sn", stderr.String())
}

2。具有通道的标准输出管道

我们通常不像你的代码那样返回通道,因为它们保存和移动数据的用法与变量不同。我们将它们作为参数传递给函数,并从不同的进程(例程)读取/写入这些通道。

你可以使用StdoutPipe()方法从管道中获取输出,如io. readclose。然后用bufio.Scanner读取。如你所见,我在这里使用了channel

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()
}
}

通道是连接并发程序的管道。您可以从一个运行例程向通道发送值,并从另一个运行例程接收这些值。如果没有使用缓冲通道,则发送和接收阻塞,直到另一方准备好。返回的通道可能不是合适的通道使用。

有两个选项可以解决你的问题

Option1:不使用通道,只是简单地返回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)
}

Option2:使用通道但不返回。创建一个通道并将其作为参数传递,并在main()中的receive上保持阻塞。因此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)
}

最新更新