Ctrl+C 如何 传入到exec.Command调用的命令中

karl_zhao · 2021-12-15 17:07:48 · 1384 次点击

不好意思,我以为你要做的是在程序开启的程序里面读取标准输入

我看了看你的代码,大概明白了你的意思

主程序运行后

  • 运行子程序
  • 等待系统信号

子程序运行后

  • 等待系统信号

现在在主程序上输入系统信号 os.Interrupt

主程序获取信号后退出 子程序获取信号后执行其他逻辑


按照你的 Command 的做法 你相当于是在程序内开了一个 shell 然后在 shell 内再运行你写的 myFakeTool

你当前的主程序是父进程 你里面的 Shell 是子进程 当你 Ctrl+C 终止父进程时 子进程就变成了孤儿进程被挂起

#3
更多评论

1楼 @Mericusta 请指教! 我做了一个demo示例,Go程序调用的一个子程序myFakeTool,很简单的代码生成的。

myFakeTool的代码:

func main(){

sigChan := make(chan os.Signal)

signal.Notify(sigChan)

select{
case sig:=<-sigChan:
    fmt.Println("接受到来自系统的信号:",sig)
}

}

myFakeTool就是模拟一个引用Ctrl+C信号的小程序。

主Go程序如下:

func subProgram() {

cmdString := "myFakeTool This_Is_Test_For_Ctrl_C"

cmd := exec.Command(os.Getenv("SHELL"), "-c", cmdString)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin

cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}

fmt.Println(cmdString, "...")
err := cmd.Run()
if err != nil {
    fmt.Println("Command Error!")
}

fmt.Printf("pid is %0d.\n", cmd.Process.Pid)

}

func main() {

globalWg.Add(1)
go func() {
    subProgram()
    globalWg.Done()
}()
fmt.Println("start main programme.")

time.Sleep(time.Duration(10) * time.Second)
time.Sleep(time.Duration(100) * time.Second)

globalWg.Wait()
fmt.Println("end main programme.")

}

可是程序运行起来没有达到效果,子程序没有捕捉到Ctrl+C。

请大佬指点!

#2