bash 从以另一个用户身份运行的后台进程获取 PID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6197165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting a PID from a Background Process Run as Another User
提问by Dex
Getting a background process ID is easy to do from the prompt by going:
通过以下方式从提示中获取后台进程 ID 很容易:
$ my_daemon &
$ echo $!
But what if I want to run it as a different user like:
但是如果我想以不同的用户身份运行它怎么办:
su - joe -c "/path/to/my_daemon &;"
Now how can I capture the PID of my_daemon?
现在如何捕获 my_daemon 的 PID?
回答by Jonathan Leffler
Succinctly - with a good deal of difficulty.
简洁 - 有很多困难。
You have to arrange for the su'd shell to write the child PID to a file and then pick the output. Given that it will be 'joe' creating the file and not 'dex', that adds another layer of complexity.
您必须安排 su'd shell 将子 PID 写入文件,然后选择输出。鉴于将是 'joe' 创建文件而不是 'dex',这就增加了另一层复杂性。
The simplest solution is probably:
最简单的解决方案可能是:
su - joe -c "/path/to/my_daemon & echo $! > /tmp/su.joe.$$"
bg=$(</tmp/su.joe.$$)
rm -f /tmp/su.joe.$$ # Probably fails - joe owns it, dex does not
The next solution involves using a spare file descriptor - number 3.
下一个解决方案涉及使用备用文件描述符 - 编号 3。
su - joe -c "/path/to/my_daemon 3>&- & echo $! 1>&3" 3>/tmp/su.joe.$$
bg=$(</tmp/su.joe.$$)
rm -f /tmp/su.joe.$$
If you're worried about interrupts etc (and you probably should be), then you trap things too:
如果您担心中断等(您可能应该担心),那么您也会陷入困境:
tmp=/tmp/su.joe.$$
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
su - joe -c "/path/to/my_daemon 3>&- & echo $! 1>&3" 3>$tmp
bg=$(<$tmp)
rm -f $tmp
trap 0 1 2 3 13 15
(The caught signals are HUP, INT, QUIT, PIPE and TERM - plus 0 for shell exit.)
(捕获的信号是 HUP、INT、QUIT、PIPE 和 TERM - 加上 0 表示 shell 退出。)
Warning: nice theory - untested code...
警告:很好的理论 - 未经测试的代码......
回答by Dave
The approaches presented here didn't work for me. Here's what I did:
这里介绍的方法对我不起作用。这是我所做的:
PID_FILE=/tmp/service_pid_file
su -m $SERVICE_USER -s /bin/bash -c "/path/to/executable $ARGS >/dev/null 2>&1 & echo $! >$PID_FILE"
PID=`cat $PID_FILE`
回答by koola
Here's my solution
这是我的解决方案
su oracle -c "/home/oracle/database/runInstaller" &
pid=$(pgrep -P $!)
Explantation
解释
pgrep -P $!- Gets the child process of the parent pid$!
pgrep -P $!- 获取父pid的子进程$!
回答by pmoench
I took the above solution by Linux, but had to add a sleep to give the child process a chance to start.
我采用了Linux的上述解决方案,但不得不添加一个睡眠让子进程有机会启动。
su - joe -c "/path/to/my_daemon > /some/output/file" &
parent=$!
sleep 1
pid=$(pgrep -P $parent)
Running in bash, it doesn't like pid=$(pgrep -P $!)but if I add a space after the !it's ok: pid=$(pgrep -P $! ). I stuck with the extra $parentvariable to remind myself what I'm doing next time I look at the script.
在 bash 中运行,它不喜欢,pid=$(pgrep -P $!)但如果我在!它之后添加一个空格就可以了:pid=$(pgrep -P $! ). 我坚持使用额外的$parent变量来提醒自己下次查看脚本时我在做什么。

