如果我在脚本中运行此命令,它不会生成除来自以下内容的标头之外的输出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 。$$