たとえば、
$ cat foo.sh
#!/usr/bin/env bash
while true; do sleep 1 ; done
$ ./foo.sh &
$ pgrep foo.sh
$
比較:
$ cat bar.sh
#!/bin/bash
while true; do sleep 1 ; done
$ ./bar.sh &
$ pgrep bar.sh
21202
次のコマンドで開始されたプロセスが出力env bash
に表示されますps aux
。
terdon 4203 0.0 0.0 26676 6340 pts/3 S 17:23 0:00 /bin/bash
/bin/bash
ディスプレイの始まり
terdon 9374 0.0 0.0 12828 1392 pts/3 S 17:27 0:00 /bin/bash ./bar.sh
これがおそらく当初はキャプチャされていない理由を説明しているようですpgrep
。したがって、質問は次のようになります。
- 呼び出し時にスクリプト名が表示されないのはなぜですか
env
? pgrep
出力は単に解析されますかps
?pgrep
実行中のスクリプトを表示できるようにこの問題を解決する方法はありますかenv
?
ベストアンサー1
質問1
envを介して呼び出すときにスクリプト名が表示されないのはなぜですか?
~から体本ウィキペディア記事:
Unixファミリーのオペレーティングシステムでは、shebangを持つスクリプトがプログラムとして実行されると、プログラムローダはスクリプトの最初の行の残りの部分をインタプリタコマンドで解析し、代わりに指定されたインタプリタを実行してスクリプトを実行しようとします。最初に使用されたパスはパラメータとして渡されます。
したがって、これが意味するのは、スクリプトの名前がカーネルに知られているプロセス名ですが、それを呼び出した直後にローダーが引数を実行し、残りのスクリプトを引数として渡すということ#!
です。
しかし、env
そうしないでください。呼び出されると、カーネルはスクリプト名を知ってそれを実行しますenv
。env
次に、$PATH
実行する実行可能ファイルを検索します。
次にenv
インタプリタを実行します。スクリプトの元の名前は知らず、カーネルだけを知っています。この時点で、env
ファイルの残りの部分が解析され、呼び出されたばかりのインタプリタに渡されます。
質問#2
pgrepは単にpsの出力を解析しますか?
はい、そうです。ps
使用しているのと同じCライブラリを呼び出します。これは単なる包装紙以上ですps
。
質問#3
pgrepがenvを介して起動されたスクリプトを表示できるように、この問題を解決する方法はありますか?
出力に実行可能ファイルの名前を表示できますps
。
$ ps -eaf|grep 32405
saml 32405 24272 0 13:11 pts/27 00:00:00 bash ./foo.sh
saml 32440 32405 0 13:11 pts/27 00:00:00 sleep 1
この場合、pgrep -f <name>
実行可能ファイルだけでなくコマンドライン引数全体を検索するので、それを使用して実行可能ファイルを見つけることができます。
$ pgrep -f foo
32405