
スクリプトでこのコマンドを実行すると、次のヘッダー以外に出力は生成されません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を表示できます。セッションおよびプロセスグループは通常シェルジョブ制御に使用されます(したがって名前-j
)。
ターミナルエミュレータはこのプロセスを使用して新しいセッションを作成し、そのセッションを再利用して優先シェルを実行します。したがって、端末では、セッションIDは通常シェルのpidと同じです。
だからps -j -s "$$"
、それシェルを使用すると、セッションからプロセスを取得できます。"$$"
発生するセッション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
ps
2番目のコマンドps
が示すように、ID 21044のプロセスがセッションリーダーではないため、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を取得します。$$