exec.Command的问题请教

NeptuneNeptune · 2021-10-18 10:15:09 · 1180 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2021-10-18 10:15:09 的主题,其中的信息可能已经有所发展或是发生改变。

我是一个golang新手,目前遇到了一个问题。先上代码

func main() {
    cancelFunc, err := tool.ExecCommand("ping -t www.baidu.com")
    if err != nil {
        if cancelFunc != nil {
            cancelFunc()
        }
        logger.Printf("%v", err)
    } else {
        time.Sleep(12 * time.Second)
        cancelFunc()
    }
    logger.Println("================")
    time.Sleep(12 * time.Second)
    logger.Println("end")
}

func ExecCommand(cmd string) (context.CancelFunc, error) {
    ctx, cancel := context.WithCancel(context.TODO())
    process := exec.CommandContext(ctx, "cmd", "/c", cmd)
    output, err := process.StdoutPipe()
    if err != nil {
        logger.Printf("命令执行异常:%v", err)
        if cancel != nil {
            cancel()
        }
        return nil, err
    }
    err = process.Start()
    if err != nil {
        logger.Printf("命令执行异常:%v", err)
        if cancel != nil {
            cancel()
        }
        return nil, err
    }
    go func() {
        logger.Printf("进程PID:%d", process.Process.Pid)
        defer func(proc *os.Process) {
            pid := proc.Pid
            err := proc.Kill()
            if err != nil {
                logger.Printf("关闭进程失败,PID:%d,%s", pid, err)
            }
        }(process.Process)
        reader := bufio.NewReader(output)
        for {
            select {
            case <-ctx.Done():
                logger.Printf("命令执行完毕!")
                return
            default:
                line, err := reader.ReadString('\n')
                if err != nil || err == io.EOF {
                    return
                }
                logger.Printf("%s", line)
            }
        }
    }()
    return cancel, err
}

我遇到的问题是,就上述代码,我运行一个ping -t的命令做测试,在这个方法外部十秒后调用了cancelFunc,程序是停了,golang启动的叫做Console的进程也停了,但是操作系统上依然有一个叫做PING的进程一直在执行没有结束。 我想向各位大佬请教一下,怎样在能在这个process退出时,让它启动的ping命令也结束运行。当然了,这个Ping只是一个例子,代指被exec.Command启动的操作系统上的程序。先在这里谢过了。


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

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1180 次点击  
加入收藏 微博
6 回复  |  直到 2021-11-11 09:46:55
eirueirufu
eirueirufu · #1 · 3年之前

kill好像多余了,你可以搜下go怎么关闭子进程

NeptuneNeptune
NeptuneNeptune · #2 · 3年之前
eirueirufueirueirufu #1 回复

kill好像多余了,你可以搜下go怎么关闭子进程

我本来是没写kill的,但是发现有系统进程残留,就试了试这个kill,发现他关掉的是Console,不写这个其实也会关掉。只是没有删除它。还有我来发帖我肯定已经在网上找了很久的答案了呀,但是没找到解决办法,没有类似的问题描述。

Yanwenjiepy
Yanwenjiepy · #3 · 3年之前

c.Process.Signal(syscall.SIGTERM)

Yanwenjiepy
Yanwenjiepy · #4 · 3年之前

start完wait一下,你可以在goroutine里杀死ping 进程,wait调用返回,main goroutine退出。要么就是制造孤儿进程和僵尸进程

Yanwenjiepy
Yanwenjiepy · #5 · 3年之前

而且 cancelfunc 放到main里声明,传到你封装的函数里

lysShub
lysShub · #6 · 3年之前

exec.CommandContext 不要写cmd,直接运行ping

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传