从bash脚本启动进程时的不同pid

时间:2018-05-17 17:59:35

标签: linux bash pid

我正在写init.d脚本,我遇到了保存分叉进程pid的问题。

这是我的初始脚本:

sudo -u $USER nohup -- nice -n "0" java Test >> /dev/null 2>&1 < /dev/null &
NEWPID="$!"
echo $NEWPID

但是当我运行这个脚本时,我打印了以下pid

$./scr.sh
4595

但是

$ps  | grep java
 4596 pts/23   00:00:01 java

正如您所看到的,pid不同(45964595)。但如果试着写下以下内容:

java Test &
NEWPID="$!"
echo $NEWPID

我得到了正确的结果:

$./scr.sh
4653
$ps  | grep java
 4653 pts/23   00:00:03 java

第一个出了什么问题?

2 个答案:

答案 0 :(得分:2)

在效率低下的世界中,会涉及多个过程:

<the shell>   1234
    |
    |
  sudo        4595
    |
    |
  nohup       4596
    |
    |
  nice        4597
    |
    |
  java        4598

$!仅指进程在后台由shell本身启动,这是运行sudo的进程。 java,您感兴趣的过程正在进行中4598.您需要使用ps(或其他一些工具)来获取该进程ID,因为shell不会知道它。

真正的世界中,涉及的流程并不多,因为并非上述链中的每个工作都必须分叉一个新流程;其中一些人可以简单地使用exec来代替他们运行的程序。我认为 sudonice都这样做(nohup必须在不同的流程组中启动新流程才能完成它的工作)。所以链看起来更像是

<the shell>      1234
    |
    |
 sudo/nohup      4595
    |
    |
 nice/java       4596

但最终结果是一样的; shell无法获取java最终运行的进程的进程ID。

答案 1 :(得分:1)

尝试在启动后台进程的同一个shell中打印$!

NEWPID=$(sudo -u $USER bash -c "nohup -- nice -n 0 java Test >/dev/null 2>&1 </dev/null & echo $!")
echo $NEWPID