79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"bufio"
|
|||
|
"context"
|
|||
|
"fmt"
|
|||
|
"io"
|
|||
|
"os/exec"
|
|||
|
"sync"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
func main() {
|
|||
|
//ctx, cancel := context.WithCancel(context.Background())
|
|||
|
//go func(cancelFunc context.CancelFunc) {
|
|||
|
// time.Sleep(10 * time.Second)
|
|||
|
// cancelFunc()
|
|||
|
//}(cancel)
|
|||
|
//err := Command(ctx, "ping www.baidu.com")
|
|||
|
//if err != nil {
|
|||
|
// return
|
|||
|
//}
|
|||
|
//err := RunWithTimeout(10*time.Second, "ping www.baidu.com")
|
|||
|
//if err != nil {
|
|||
|
// return
|
|||
|
//}
|
|||
|
err := RunCmd("ping www.baidu.com")
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func RunWithTimeout(timeout time.Duration, cmd string) error {
|
|||
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|||
|
defer cancel()
|
|||
|
return Command(ctx, cmd)
|
|||
|
}
|
|||
|
|
|||
|
func RunCmd(cmd string) error {
|
|||
|
return Command(context.Background(), cmd)
|
|||
|
}
|
|||
|
|
|||
|
func Command(ctx context.Context, cmd string) error {
|
|||
|
// c := exec.CommandContext(ctx, "cmd", "/C", cmd)
|
|||
|
c := exec.CommandContext(ctx, "bash", "-c", cmd) // mac linux
|
|||
|
stdout, err := c.StdoutPipe()
|
|||
|
if err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
var wg sync.WaitGroup
|
|||
|
wg.Add(1)
|
|||
|
go func(wg *sync.WaitGroup) {
|
|||
|
defer wg.Done()
|
|||
|
reader := bufio.NewReader(stdout)
|
|||
|
for {
|
|||
|
// 其实这段去掉程序也会正常运行,只是我们就不知道到底什么时候Command被停止了,而且如果我们需要实时给web端展示输出的话,这里可以作为依据 取消展示
|
|||
|
select {
|
|||
|
// 检测到ctx.Done()之后停止读取
|
|||
|
case <-ctx.Done():
|
|||
|
if ctx.Err() != nil {
|
|||
|
fmt.Printf("程序出现错误: %q", ctx.Err())
|
|||
|
} else {
|
|||
|
fmt.Println("程序被终止")
|
|||
|
}
|
|||
|
return
|
|||
|
default:
|
|||
|
readString, err := reader.ReadString('\n')
|
|||
|
if err != nil || err == io.EOF {
|
|||
|
return
|
|||
|
}
|
|||
|
fmt.Print(readString)
|
|||
|
}
|
|||
|
}
|
|||
|
}(&wg)
|
|||
|
err = c.Start()
|
|||
|
wg.Wait()
|
|||
|
return err
|
|||
|
}
|