英文:
golang exec background process and get its pid
问题
情况:
我想运行一个将自己放入后台的命令。如果可能的话,我会在前台运行该命令,并自己将其放入后台。
问题:
当进程在后台运行时,我如何使用Go获取它的pid
?
我尝试了以下方法:
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()
这会立即返回,并在后台运行ssh
。但它的pid
不是正在运行的ssh
进程的pid
。而且,它是在ssh
进程分叉并将自己放入后台之前的父ssh
进程的pid
。
英文:
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.
答案1
得分: 38
你不需要任何特殊的东西,只需不要告诉ssh将自己放到后台,并且不要使用Wait()
等待它。以下是一个示例:
$ 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
希望对你有所帮助!
英文:
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
答案2
得分: 5
@Mostafa Hussein,可以使用goroutine进行等待和管理进程。
func main() {
cmd := exec.Command("shell.sh")
err := cmd.Start()
if err != nil {
return err
}
pid := cmd.Process.Pid
// 使用goroutine进行等待和管理进程
// 这很重要,否则进程会变为S模式
go func() {
err = cmd.Wait()
fmt.Printf("命令执行完毕,错误信息:%v", err)
}()
return nil
}
英文:
@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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论