请教一下各位大佬,
用go做了一个小工具,调度服务器上的各种工具运行,通过exec.command调用了多个命令行运行不同的工具。
现在遇到了一个问题,使用ctrl+c可以控制程序的结束,现在有一个工具"Tool_A"对于ctrl+c是调用它的命令行交互模式。
比如说:有一个命令行脚本run_tool_a是运行Tool_A的。
在go代码里面执行exec.Command("run_tool_a"),想实现一个功能就是运行过程中通过在terminal按下ctrl+c,
那么就能触发Tool_A的命令行交互模式,这样可以通过tcl命令来控制Tool_A的运行动作。
我不知道如何配置exec.Command来实现这个功能,试了几次没有搞定,特地请教大佬们!
谢谢!
1楼 <a href="/user/Mericusta" title="@Mericusta">@Mericusta</a> 请指教!
我做了一个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
更多评论
不好意思,我以为你要做的是在程序开启的程序里面读取标准输入
我看了看你的代码,大概明白了你的意思
主程序运行后
- 运行子程序
- 等待系统信号
子程序运行后
- 等待系统信号
---
现在在主程序上输入系统信号 os.Interrupt
主程序获取信号后退出
子程序获取信号后执行其他逻辑
---
按照你的 Command 的做法
你相当于是在程序内开了一个 shell
然后在 shell 内再运行你写的 myFakeTool
你当前的主程序是父进程
你里面的 Shell 是子进程
当你 Ctrl+C 终止父进程时
子进程就变成了孤儿进程被挂起
#3