Bash
互動式 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
問題:
你能解釋一下區別並告訴我正確的方法嗎?
我已經嘗試了很多東西並在 google 上搜尋了 4 個小時,如果您需要我可以列出我嘗試過的內容,但我認為這與這裡無關。
$echo $SHELL /bin/bash
和:
$head -1 testing.bash #!/bin/bash
ps
’-s sessionid
選項是根據會話 ID 選擇程序。您可以使用
ps -j
查看程序的會話 ID。會話和程序組通常用於 shell 作業控制(因此是-j
)。您的終端仿真器使用該程序創建一個新會話,然後重用該會話來執行您首選的 shell。因此,在終端中,會話 ID 通常與該 shell 的 pid 相同。
因此,如果您
ps -j -s "$$"
在該shell 中執行,您將獲得會話中的程序,因為"$$"
恰好與會話 ID 相同。如果您在任何其他 shell 中執行該命令(例如在子程序中執行以解釋您的
testing
腳本的 shell),任何不是會話領導者的 shell,您將一無所獲,因為沒有對應於 id 的會話該外殼的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。