交互式 shell 中会话中的进程与脚本中的进程

交互式 shell 中会话中的进程与脚本中的进程

如果我在脚本中运行此命令,它不会生成除来自以下内容的标头之外的输出ps

 # Taken from Advanced Bash Usage on youtube:

 echo "$(echo "$(echo "$(echo "$(ps wwf -s $$)")")")"

这是输出:

$./testing.bash
  PID TTY      STAT   TIME COMMAND

但这里它在终端中运行,产生预期产出:

$echo "$(echo "$(echo "$(echo "$(ps wwf -s $$)")")")"
  PID TTY      STAT   TIME COMMAND
18289 pts/4    Ss+    0:00 /bin/bash
17917 pts/4    S+     0:00  \_ /bin/bash
17918 pts/4    S+     0:00      \_ /bin/bash
17919 pts/4    S+     0:00          \_ /bin/bash
17920 pts/4    S+     0:00              \_ /bin/bash
17921 pts/4    R+     0:00                  \_ ps wwf -s 18289

问题:

您能解释一下其中的区别并告诉我正确的方法吗?

我已经尝试了很多东西,并在谷歌上搜索了 4 个小时,如果你需要,我可以列出我尝试过的内容,但我认为这与这里无关。

$echo $SHELL
/bin/bash

和:

$head -1 testing.bash 
#!/bin/bash

答案1

ps'-s sessionid选项是根据会话 ID 选择进程。

您可以使用ps -j查看进程的会话 ID。会话和进程组通常用于 shell 作业控制(因此称为-j)。

您的终端模拟器使用该进程创建一个新会话,然后重用该会话来执行您首选的 shell。因此,在终端中,会话 id 通常与该 shell 的 pid 相同。

所以,如果你跑ps -j -s "$$"跑进shell,您将获得会话中的进程,因为"$$" 发生与会话 ID 相同。

如果您在任何其他 shell(例如在子进程中执行来解释脚本的 shell testing)中运行该命令,任何不是会话领导者的 shell 中,您都不会得到任何结果,因为没有 id 对应的会话该 shell 的 pid。

$ ps -j -s "$$"
  PID  PGID   SID TTY          TIME CMD
 7239  7239  7239 pts/7    00:00:00 zsh
21002 21002  7239 pts/7    00:00:00 ps

$$是 7239,会议负责人。这ps -j -s 7239给了我该会话中的所有流程。

$ sh -xc 'ps -j -s "$$"; ps -j -p "$$"'
+ ps -j -s 21044
  PID  PGID   SID TTY          TIME CMD
+ ps -j -p 21044
  PID  PGID   SID TTY          TIME CMD
21044 21044  7239 pts/7    00:00:00 sh

第一个ps命令不返回任何内容,因为如第二个命令ps所示,没有 id 21044 的会话,因为 id 21044 的进程不是会话领导者。会话领导者仍然是 7239,由终端仿真器启动的 shell。

$ sh -xc 'ps -j -s "$(($(ps -o sid= -p "$$")))"'
+ ps -o sid= -p 21215
+ ps -j -s 7239
  PID  PGID   SID TTY          TIME CMD
 7239  7239  7239 pts/7    00:00:00 zsh
21215 21215  7239 pts/7    00:00:00 sh
21217 21215  7239 pts/7    00:00:00 ps

现在,我们看到会话中的所有进程。我们用来获取所属ps -o sid= -p "$$"会话的 id 。$$

相关内容