go语言暂停命令_golang调用shell命令(实时输出, 终止等) - Go语言中文社区

go语言暂停命令_golang调用shell命令(实时输出, 终止等)


背景

是这样的,最近在研究一个定时任务系统的改造,可能有点像jenkins做到的那种吧。

可以输入shell命令,也可以执行py脚本等等,相比之前来说,也要能够及时停止!

但是遇到了这么个问题,golang执行py脚本的时候获取不到脚本的输出。

首先来看看go里面怎么运行shell脚本吧,我比较喜欢执行全部命令。

普通用法(一次性获取所有输出)

package main

import (

"fmt"

"os/exec"

)

func main() {

Command("ls")

}

// 这里为了简化,我省去了stderr和其他信息

func Command(cmd string) error {

c := exec.Command("bash", "-c", cmd)

// 此处是windows版本

// c := exec.Command("cmd", "/C", cmd)

output, err := c.CombinedOutput()

fmt.Println(string(output))

return err

}

可以看到,当前命令执行的是输出当前目录下的文件/文件夹

image.png

实时显示

效果图:

image.png

package main

import (

"bufio"

"fmt"

"io"

"os/exec"

)

func main() {

// 执行ping baidu的命令, 命令不会结束

Command("ping www.baidu.com")

}

func Command(cmd string) error {

c := exec.Command("bash", "-c", cmd)

stdout, err := c.StdoutPipe()

if err != nil {

return err

}

go func() {

reader := bufio.NewReader(stdout)

for {

readString, err := reader.ReadString('n')

if err != nil || err == io.EOF {

break

}

fmt.Print(readString)

}

}()

return c.Run()

}

可关闭+实时输出

package main

import (

"bufio"

"context"

"fmt"

"io"

"os/exec"

"time"

)

func main() {

ctx, cancel := context.WithCancel(context.Background())

go func(cancelFunc context.CancelFunc) {

time.Sleep(3 * time.Second)

cancelFunc()

}(cancel)

Command(ctx, "ping www.baidu.com")

}

func Command(ctx context.Context, cmd string) error {

c := exec.CommandContext(ctx, "bash", "-c", cmd)

stdout, err := c.StdoutPipe()

if err != nil {

return err

}

go func() {

reader := bufio.NewReader(stdout)

for {

// 其实这段去掉程序也会正常运行,只是我们就不知道到底什么时候Command被停止了,而且如果我们需要实时给web端展示输出的话,这里可以作为依据 取消展示

select {

// 检测到ctx.Done()之后停止读取

case

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 {

break

}

fmt.Print(readString)

}

}

}()

return c.Run()

}

效果图:

image.png

可以看到输出了3次(1秒1次)之后程序就被终止了,确切的说是读取输出流的循环结束了。

执行Python脚本(阻塞)

其实很简单,只要python -u xxx.py这样执行就可以了, -u参数

简单的说就是python的输出是有缓存的,-u会强制往标准流输出,当Python脚本阻塞的时候

也不会拿不到输出!

其他

"bash" 和"-c",据我的观察,这2个参数代表在当前cmd窗口执行,而不加这2个参数,直接上shell的话,会启动一个新窗口,目前观察是stdout拿不到数据。

有疑问加站长微信联系(非本文作者)

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39960793/article/details/111834486
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-06-14 13:53:28
  • 阅读 ( 916 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢