このコマンドをスクリプトで実行すると、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を確認します。プロセスグループとともにセッションは、通常、シェルジョブ制御に使用されます(したがって、-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のプロセスはセッションリーダーではないため、ID21044のセッションはありません。セッションリーダーはまだ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を取得します に属します。