web-dev-qa-db-ja.com

対話型シェルでのセッションとスクリプトでのプロセス

このコマンドをスクリプトで実行すると、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
4

ps '-s sessionidオプションは、セッションIDに基づいてプロセスを選択することです。

ps -jを使用して、プロセスのセッションIDを確認できます。プロセスグループと共にセッションは、通常、シェルジョブ制御に使用されます(つまり、-j)。

ターミナルエミュレータは、プロセスを使用して新しいセッションを作成し、それを再利用して優先シェルを実行します。したがって、ターミナルでは、セッションIDは通常、そのシェルのpidと同じになります。

つまり、ps -j -s "$$"thatシェルで実行すると、"$$"happensセッションIDと同じです。

他のシェル(testingスクリプトを解釈するために子プロセスで実行されるシェルなど)、セッションリーダーではないシェルでそのコマンドを実行すると、セッションがないため何も得られません。そのシェルのpidに対応するidを持ちます。

$ 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

2番目のpsが示すように、最初のpsコマンドは何も返しません。id21044のプロセスはセッションリーダーではないため、id 21044のセッションはありません。セッションリーダーは7239のままで、シェルはターミナルエミュレーターによって起動されます。

$ 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を取得しました。

10