从后台进程获取PID作为另一个用户运行

时间:2011-06-01 06:33:36

标签: bash pid su

通过以下方式从提示中轻松获取后台进程ID:

$ my_daemon &
$ echo $!

但是,如果我想以不同的用户身份运行它,例如:

su - joe -c "/path/to/my_daemon &;"

现在我如何捕获my_daemon的PID?

5 个答案:

答案 0 :(得分:13)

简洁 - 有很多困难。

您必须安排su'd shell将子PID写入文件,然后选择输出。鉴于它将'joe'创建文件而不是'dex',这会增加另一层复杂性。

最简单的解决方案可能是:

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

下一个解决方案涉及使用备用文件描述符 - 数字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.$$

如果你担心中断等(你可能应该这样),那么你也会陷入困境:

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

(捕获的信号是HUP,INT,QUIT,PIPE和TERM - 加上0退出shell。)

警告:好理论 - 未经测试的代码......

答案 1 :(得分:1)

这里介绍的方法对我不起作用。这是我做的:

core.pager
    [...]

    When the LESS environment variable is unset, Git sets it to FRX
    (if LESS environment variable is set, Git does not change it at
    all). If you want to selectively override Git’s default setting
    for LESS, you can set core.pager to e.g.  less -S. This will be
    passed to the shell by Git, which will translate the final
    command to LESS=FRX less -S. [...]

答案 2 :(得分:1)

只要重定向了后台进程的输出,就可以将PID发送到stdout:

su "${user}" -c "${executable} > '${log_file}' 2>&1 & echo \$!"

然后可以将PID重定向到第一个用户而不是第二个用户拥有的文件。

su "${user}" -c "${executable} > '${log_file}' 2>&1 & echo \$!" > "${pid_file}"

尽管如此,日志文件确实需要由第二个用户拥有。

答案 3 :(得分:-1)

这是我的解决方案

su oracle -c "/home/oracle/database/runInstaller" &
pid=$(pgrep -P $!)

外植

  • pgrep -P $! - 获取父pid $!
  • 的子进程

答案 4 :(得分:-1)

我在Linux上采用了上述解决方案,但是必须添加一个睡眠以便让子进程有机会启动。

su - joe -c "/path/to/my_daemon > /some/output/file" &
parent=$!
sleep 1
pid=$(pgrep -P $parent)

在bash中运行,它不喜欢pid=$(pgrep -P $!)但是如果我在!之后添加一个空格就可以了:pid=$(pgrep -P $! )。我坚持使用额外的$parent变量来提醒自己下次看剧本时我在做什么。