使用 ps 和 pgrep 检查 /sbin/init 的进程 ID

使用 ps 和 pgrep 检查 /sbin/init 的进程 ID

以下命令不返回任何结果

ps -C init -o pid=
ps -C /sbin/init -o pid=
pgrep -x /sbin/init

其中以下命令给出的输出如下:

$ ps -ealf | grep init
4 S root         1     0  0  80   0 -  6266 -      08:35 ?        00:00:03 /sbin/init auto noprompt

$ pidof init
1

我想知道如何使用 init 进程获取 PID聚苯乙烯-C程序包方法。我在这里做错了什么?

我使用的是 Ubuntu 16.04.3 LTS,内核为 4.10.0-27-generic 32 位

答案1

在 Ubuntu 16.04 上,/sbin/init是 systemd 的符号链接:

$ readlink /sbin/init
/lib/systemd/systemd
$ sudo readlink /proc/1/exe
/lib/systemd/systemd
$ sudo xargs -0a /proc/1/cmdline
/sbin/init splash

ps -C读取 中的命令名称/proc/<pid>/stat。看man 5 proc:

/proc/[pid]/stat
      Status information about the process.  This is used by ps(1).
      It is defined in the kernel source file fs/proc/array.c.
      ...

      (2) comm  %s
                The filename of the executable, in parentheses.
                This is visible whether or not the executable is
                swapped out.

由于 systemd 支持将自身重新执行为 init (例如, ),因此如果作为 启动,它会尝试尽快systemctl daemon-reexec将其更改为。从systemd/sbin/init来源:

/* If we get started via the /sbin/init symlink then we are called 'init'. After a subsequent reexecution we
 * are then called 'systemd'. That is confusing, hence let's call us systemd right-away. */
program_invocation_short_name = systemd;
(void) prctl(PR_SET_NAME, systemd);

因此,ps -C init不会匹配 PID 1 的 systemd。有了pgrep,您可以使用-f

$ ps -C systemd
  PID TTY          TIME CMD
    1 ?        00:00:01 systemd
 1261 ?        00:00:00 systemd

$ pgrep -f /sbin/init
1

pgrep -f检查/proc/<pid>/cmdline,并且 systemd 不会尝试更改它。输出systemd中的第二个ps是我的用户会话初始化。

答案2

任何使用 systemd 而不使用 sysvcompat 的系统都会像这样。尽管 /sbin/init 是 systemd 的链接,但命令名称仍然是 systemd。当使用 ps 的 -C 选项时,这只会查找 systemd。当使用 ps 的 -f 选项时,意味着完整格式会在 CMD 列中打印命令参数 (args) 而不是命令名称 (comm),并且 systemd 确实正在开始使用该文件/sbin/init

尝试这个命令:

ps --pid=1 -o cmd,comm

实际上,这还包括其他参数(如果有的话),并且这也意味着 Unix 中的参数由于符号链接可能会导致它们指向完全不同的命令名称。

相关内容