gpt4 book ai didi

Golang - 将 exec 输出复制到缓冲区

转载 作者:数据小太阳 更新时间:2023-10-29 03:14:55 25 4
gpt4 key购买 nike

我正在编写一个函数来执行一个程序并返回 stdout 和 stderr。它还可以选择将输出显示到控制台。我显然不是在等待什么,就好像我连续两次运行该函数一样,输出是不同的。这是一个示例程序,将 dir var 替换为包含大量文件的目录以填充缓冲区:

func main() {
dir := "SOMEDIRECTORYWITHALOTOFFILES"
out, err := run("ls -l "+dir, true)
if err != nil {
log.Fatalf("run returned %s", err)
}
log.Printf("Out: %s", out)
out2, err := run("ls -l "+dir, false)
if err != nil {
log.Fatalf("run returned %s", err)
}
log.Printf("Out2: %s", out2)
if out != out2 {
log.Fatalf("Out mismatch")
}
}

func run(cmd string, displayOutput bool) (string, error) {
var command *exec.Cmd
command = exec.Command("/bin/sh", "-c", cmd)
var output bytes.Buffer

stdout, err := command.StdoutPipe()
if err != nil {
return "", fmt.Errorf("Unable to setup stdout for command: %v", err)
}
go func() {
if displayOutput == true {
w := io.MultiWriter(os.Stdout, &output)
io.Copy(w, stdout)
} else {
output.ReadFrom(stdout)
}
}()

stderr, err := command.StderrPipe()
if err != nil {
return "", fmt.Errorf("Unable to setup stderr for command: %v", err)
}
go func() {
if displayOutput == true {
w := io.MultiWriter(os.Stderr, &output)
io.Copy(w, stderr)
} else {
output.ReadFrom(stderr)
}
}()
err = command.Run()
if err != nil {
return "", err
}
return output.String(), nil
}

最佳答案

这是对您的示例进行的简化且有效的修订。请注意,测试命令已换出,以便我可以在 Windows 中进行测试,并且为了简洁起见,您的错误检查已被省略。

关键的变化是 sync.WaitGroup 阻止 run 函数打印输出并返回,直到 goroutine 指示它已完成。

func main() {
dir := "c:\\windows\\system32"
command1 := exec.Command("cmd", "/C", "dir", "/s", dir)
command2 := exec.Command("cmd", "/C", "dir", "/s", dir)
out1, _ := run(command1)
out2, _ := run(command2)
log.Printf("Length [%d] vs [%d]\n", len(out1), len(out2))
}

func run(cmd *exec.Cmd) (string, error) {
var output bytes.Buffer
var waitGroup sync.WaitGroup

stdout, _ := cmd.StdoutPipe()
writer := io.MultiWriter(os.Stdout, &output)

waitGroup.Add(1)
go func() {
defer waitGroup.Done()
io.Copy(writer, stdout)
}()

cmd.Run()
waitGroup.Wait()
return output.String(), nil
}

关于Golang - 将 exec 输出复制到缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39007498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com