duanduan1993 2018-10-21 10:16
浏览 115

在Go中启动后守护进程

I have a system I need to operate as a daemon, which has been developed in go. Ordinarily I could just manage this though something like systemd or even just something as simple as './project &' but this particular project needs to get some input before it can become a daemon - it needs a password to be entered.

This password cannot be provided as command line args, placed in a config file, hard coded in the source etc. It must be manually provided by someone who has knowledge of the password at system startup.

At startup, the project needs to collect the password, verify that things are correct, and only if the correct password has been provided (verified by attempting to decrypt a certificate) can it then actually begin to operate as the daemon.

Is there any way in go for the project to startup, accept input from stdin, perform whatever validation is needed etc, and only then become a daemon process (detaching from stdin etc)?

Currently I can simulate the required behavior by starting it, and after the password has been entered using 'ctrl+z' to suspend it and bg to push the process to the background. Surely there has to be a way of doing that from within the process itself...

  • 写回答

2条回答 默认 最新

  • doudi5291 2018-10-21 15:08
    关注

    You could use flags and carefully control your app flow and run itself as a daemon if a given flag (such as encrypted credentials) is passed. Or even store them in a temporary file, database or anywhere.

    func main() {
    
        cred := flag.String("cred", "", "raw cred")
    
        flag.Parse()
    
        if *cred == "" {
            fmt.Print("Enter credentials:
    ")
            decryptedCred, _ := bufio.NewReader(os.Stdin).ReadString('
    ')
    
            if !validCred(decryptedCred) {
                os.Exit(1)
            }
    
            encryptedCred := encryptCredentials(decryptedCred)
    
            cmd := exec.Command("./project", fmt.Sprintf("-cred=%s", encryptedCred), "&")
            cmd.Start()
    
            fmt.Printf("Started project with pid: %d
    ", cmd.Process.Pid)
    
            os.Exit(0)
        }
    
        for {
            // start app
            // use *cred here
        }
    }
    

    Whatever the approach I would probably keep track of the pid, etc.

    ./project
    # Enter credentials:
    myCredentialsString
    # Started project with pid: 11702
    ps ax | grep project
    # 11667 s001  R      0:02.47 ./project -cred=N/esPq8wsWn4/+Gco16ddl9UnJ0= &\012
    

    Hope this helps

    评论

报告相同问题?

悬赏问题

  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数