Bash

互動式 shell 中的會話與腳本中的程序

  • June 29, 2019

如果我在腳本中執行此命令,它不會產生輸出,除了來自以下的標頭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。

引用自:https://unix.stackexchange.com/questions/527633