golang 后台进程的启动和停止

  • Post author:
  • Post category:golang


不想再像java或者其他语言那样为了操作后台程序写各种脚本的话,这篇文章值得你一看

启动命令

和上一篇文章一样,我们先来个非后台运行的启动命令

  1. func init() {
        startCmd := &cobra.Command{
            Use:   "start",
            Short: "Start Gonne",
            Run: func(cmd *cobra.Command, args []string) {
                startHttp()
            },
        }
        startCmd.Flags().BoolVarP(&daemon, "deamon", "d", false, "is daemon?")
        RootCmd.AddCommand(startCmd)
    
    }

startHttp方法启动一个http的web服务

  1. func startHttp() {
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "Hello cmd!")
        })
        if err := http.ListenAndServe(":9090", nil); err != nil {
            log.Fatal("ListenAndServe: ", err)
        }
    }

现在通过gonne start便可以启动一个web服务了,但是程序停留在命令行,如果ctrl+C程序也会终止了

命令行参数

如果想要后台启动,那么得让start命令知道是要后台运行的,参照docker命令行的方式就是加上-d,给一个命令添加参数的判断只需很少的代码

改造一下代码

  1. func init() {
        var daemon bool
        startCmd := &cobra.Command{
            Use:   "start",
            Short: "Start Gonne",
            Run: func(cmd *cobra.Command, args []string) {
                if daemon {
            fmt.Println("gonne start",daemon)        
                }
                startHttp()
            },
        }
        startCmd.Flags().BoolVarP(&daemon, "deamon", "d", false, "is daemon?")
        RootCmd.AddCommand(startCmd)
    
    }
    

命令行输入

  1. gonne start -d

复制代码

这样就可以接收到-d参数了,这里要说明一下,第一个参数取值,第二个参数代码–deamon,第三个参数代表-d

,第四个参数代码不加-d时候的默认值,第五参数是描述

后台运行

后台运行其实这里使用的是一个巧妙的方法,就是使用系统的command命令行启动自己的命令行输入,是不是有点绕,再看看看改造后的代码

  1. Run: func(cmd *cobra.Command, args []string) {
      if daemon {
        command := exec.Command("gonne", "start")
        command.Start()
        fmt.Printf("gonne start, [PID] %d running...\n", command.Process.Pid)
        ioutil.WriteFile("gonne.lock", []byte(fmt.Sprintf("%d", command.Process.Pid)), 0666)
        daemon = false
        os.Exit(0)
      } else {
        fmt.Println("gonne start")
      }
      startHttp()
    },

复制代码

用exec的Command启动刚输入的gonne start -d,就会拦截到这条请求然后通过gonne start,但是程序就不会停留在命令行了,然后发现http服务还在,还可以访问。

还有一点就是把pid输出到gonne.lock文件,给停止的程序调用

终止后台程序

有了之前的操作后,停止就简单多了

  1. func init() {
        RootCmd.AddCommand(stopCmd)
    }
    
    var stopCmd = &cobra.Command{
        Use:   "stop",
        Short: "Stop Gonne",
        Run: func(cmd *cobra.Command, args []string) {
            strb, _ := ioutil.ReadFile("gonne.lock")
            command := exec.Command("kill", string(strb))
            command.Start()
            println("gonne stop")
        },
    }

执行 gonne stop 即可终止之前启动的http服务

help命令

好了,关于命令的操作讲完了,再看看cobra给的福利,自动生成的help命令

这个不需要你做什么操作,只需要输入gonne help,相关信息已经帮你生产好了。

  1. appletekiMacBook-Pro:andev apple$ gonne help
    Usage:
      gonne [flags]
      gonne [command]
    
    Available Commands:
      help        Help about any command
      start       Start Gonne
      stop        Stop Gonne
      version     Print the version number of Gonne
    
    Flags:
      -h, --help   help for gonne
    
    Use "gonne [command] --help" for more information about a command.
    

当然,子命令也有

  1. appletekiMacBook-Pro:andev apple$ gonne start -h
    Start Gonne
    
    Usage:
      gonne start [flags]
    
    Flags:
      -d, --deamon   is daemon?
      -h, --help     help for start