Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang exec background process and get its pid

Tags:

Situation:

I want to run a command that puts itself into the background. If it makes it more possible, then I'll run the command in foreground and bring it into the background by myself.

Question:

When the process runs in background: how can I get it's pid using Go?

I tried the following:

cmd := exec.Command("ssh", "-i", keyFile, "-o", "ExitOnForwardFailure yes", "-fqnNTL", fmt.Sprintf("%d:127.0.0.1:%d", port, port), fmt.Sprintf("%s@%s", serverUser, serverIP)) cmd.Start() pid := cmd.Process.Pid cmd.Wait() 

This returns instantly and leaves ssh running in the background. But it's pid is not the pid of the running ssh process. Moreover, it's the pid of the parent ssh process before it forked and backgrounded itself.

like image 802
sbs Avatar asked Sep 15 '16 09:09

sbs


People also ask

How can we bring background process to the foreground?

We can reconnect a background job to our terminal with the Linux command fg. This command will bring job 2 into the foreground. If no job ID is given, fg will assume we're referring to the current (suspended) job.

What is Golang exec?

The exec package is defined under the OS package. It is simply a sub-package that allows you to execute external commands using Go. In this guide, we will explore how we can use the exec package in to run external commands.


2 Answers

You don't need anything special, just don't tell ssh to background itself and don't Wait() for it. Example:

$ cat script.sh #!/bin/sh sleep 1 echo "I'm the script with pid $$" for i in 1 2 3; do         sleep 1         echo "Still running $$" done $ cat proc.go package main  import (        "log"        "os"        "os/exec" )  func main() {      cmd := exec.Command("./script.sh")      cmd.Stdout = os.Stdout      err := cmd.Start()      if err != nil {         log.Fatal(err)      }      log.Printf("Just ran subprocess %d, exiting\n", cmd.Process.Pid) } $ go run proc.go 2016/09/15 17:01:03 Just ran subprocess 3794, exiting $ I'm the script with pid 3794 Still running 3794 Still running 3794 Still running 3794 
like image 92
Roman Khimov Avatar answered Sep 18 '22 19:09

Roman Khimov


@Mostafa Hussein, can use goroutine waiting, manage process

function main()     cmd := exec.Command( "shell.sh" )     err := cmd.Start()     if err != nil {         return err     }     pid := cmd.Process.Pid     // use goroutine waiting, manage process     // this is important, otherwise the process becomes in S mode     go func() {          err = cmd.Wait()         fmt.Printf("Command finished with error: %v", err)     }()     return nil } 
like image 25
Max Avatar answered Sep 17 '22 19:09

Max