Skip to content

Instantly share code, notes, and snippets.

@wjx0912
Last active April 24, 2018 07:35
Show Gist options
  • Save wjx0912/13056261abdc6bd5c34a707b1f395726 to your computer and use it in GitHub Desktop.
Save wjx0912/13056261abdc6bd5c34a707b1f395726 to your computer and use it in GitHub Desktop.
why not output?
package main
import (
"bytes"
"fmt"
"os/exec"
"time"
)
func main() {
execpath := "cmd.exe"
args := []string{"/c", "ping", "www.baidu.com", "-t"}
cmd := exec.Command(execpath, args...)
stdin, err := cmd.StdinPipe()
if err != nil {
return
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return
}
stderr, err := cmd.StderrPipe()
if err != nil {
return
}
_ = stdin
_ = stdout
_ = stderr
// ============================================
if err := cmd.Start(); err != nil {
fmt.Println("cmd.Start() error: " + err.Error())
return
}
// ============================================
go func() {
for {
var buf bytes.Buffer
if _, err := buf.ReadFrom(stdout); err != nil {
panic("buf.Read(stdout) error: " + err.Error())
}
fmt.Print(buf.String()) // 这里应该有ping的结果输出,但实际没有,为什么呢(windows平台)
}
}()
// ============================================
cmd.Wait()
for {
time.Sleep(time.Second * 1000)
}
}
@wjx0912
Copy link
Author

wjx0912 commented Apr 24, 2018

execpath := "cmd.exe"
args := []string{"/c", "ping", "www.baidu.com", "-t"}

这样也不行

@caojunxyz
Copy link

caojunxyz commented Apr 24, 2018

直接上代码吧,没有windows,macOS上go1.10.1测试ok。你这里有3个地方理解有问题,看我的代码应该可以明白。

package main

import (
	"bufio"
	"fmt"
	"io"
	"os/exec"
)

func main() {
	execpath := "ping"
	args := []string{"www.baidu.com"}

	cmd := exec.Command(execpath, args...)
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return
	}
	_ = stdin
	_ = stdout
	_ = stderr

	// ============================================
	if err := cmd.Start(); err != nil {
		fmt.Println("cmd.Start() error: " + err.Error())
		return
	}

	// ============================================
	go func() {
		for {
			buf := bufio.NewReader(stdout)
			line, err := buf.ReadString('\n')
			if err != nil {
				if err == io.EOF {
					return
				}
				panic(err)
			}
			fmt.Print(line)
		}
	}()

	// ============================================
	cmd.Wait()
}

@yrong
Copy link

yrong commented Apr 24, 2018

-t 堵死了

@wjx0912
Copy link
Author

wjx0912 commented Apr 24, 2018

这里是模拟一个子进程,然后通过pipe交互,需要用-t参数使ping不退出。
原来的代码思路上有问题,后来参考以下几篇文章解决:
golang/go#21232
https://studygolang.com/topics/1962
http://hackmongo.com/post/reading-os-exec-cmd-output-without-race-conditions/

感谢大家~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment