【问题标题】:Different pids when starting process from bash script从 bash 脚本启动进程时的不同 pid
【发布时间】:2018-05-17 17:59:35
【问题描述】:

我正在编写 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

如您所见,pids 是不同的(45964595)。但是如果尝试写如下:

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

我得到了正确的结果:

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

第一个有什么问题?

【问题讨论】:

  • sudo lanch 一个shell,然后进程再次分叉
  • 您可能正在获取(临时)sudo 进程的 PID...
  • 没有“可能”; sudo 是在后台运行的命令,所以这就是 $! 报告的内容。
  • @chepner 所以在 init.d 脚本中使用sudo ... 是个坏习惯?我必须由适当的用户运行初始化脚本?
  • @m47730 你能不能建议一个方法来解决这个问题?

标签: linux bash pid


【解决方案1】:

在一个低效的世界中,将涉及多个流程:

<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。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-04
      • 2020-03-24
      相关资源
      最近更新 更多