我正在写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
不同(4596
和4595
)。但如果试着写下以下内容:
java Test &
NEWPID="$!"
echo $NEWPID
我得到了正确的结果:
$./scr.sh
4653
$ps | grep java
4653 pts/23 00:00:03 java
第一个出了什么问题?
答案 0 :(得分:2)
在效率低下的世界中,会涉及多个过程:
<the shell> 1234
|
|
sudo 4595
|
|
nohup 4596
|
|
nice 4597
|
|
java 4598
$!
仅指进程在后台由shell本身启动,这是运行sudo
的进程。 java
,您感兴趣的过程正在进行中4598.您需要使用ps
(或其他一些工具)来获取该进程ID,因为shell不会知道它。
在真正的世界中,涉及的流程并不多,因为并非上述链中的每个工作都必须分叉一个新流程;其中一些人可以简单地使用exec
来代替他们运行的程序。我认为 sudo
和nice
都这样做(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