解決策 1:
echo $!
よりも簡単なもの ?一行として:
myCommand & echo $!
解決策 2:
sh -c
を使用できます と exec
以前でもコマンドの PID を取得する
myCommand
を開始するには 、実行を開始する前に PID が出力されるようにするには、次を使用できます。
sh -c 'echo $$; exec myCommand'
仕組み:
これにより、新しいシェルが開始され、そのシェルの PID が出力され、exec
が使用されます。 置き換えるためのビルトイン 同じ PID を持つようにします。シェルが exec
でコマンドを実行するとき 組み込み、あなたのシェルは実際になりつつあります 独自の別の PID を持ち、それがコマンドになる、それ自体の新しいコピーをフォークするというより一般的な動作ではなく、そのコマンド。
これは、非同期実行を含む代替手段よりもはるかに単純であることがわかりました (&
を使用) )、ジョブ制御、または ps
での検索 .これらのアプローチは問題ありませんが、それらを使用する特定の理由がない限り、たとえば、コマンドが既に実行されている可能性があり、その場合、その PID を検索したり、ジョブ制御を使用したりすることは理にかなっています-最初にこの方法を検討することをお勧めします. (そして、これを実現するために複雑なスクリプトやその他のプログラムを作成することは絶対に考えません)。
この回答には、この手法の例が含まれています。
そのコマンドの一部を省略できる場合もありますが、通常は省略できません。
使用しているシェルが Bourne スタイルであり、したがって exec
をサポートしている場合でも これらのセマンティクスが組み込まれているため、通常は sh -c
の使用を避けるべきではありません (または同等の) 新しい、別の この目的のためのシェル プロセス:
- シェルが
myCommand
になったら 、後続のコマンドを実行するのを待っているシェルはありません。sh -c 'echo $$; exec myCommand; foo
foo
を実行しようとすることはできません 自分自身をmyCommand
に置き換えた後 .これを最後のコマンドとして実行するスクリプトを作成していない限り、echo $$; exec myCommand
だけを使用することはできません 他のコマンドを実行しているシェルで。 - これにはサブシェルを使用できません。
(echo $$; exec myCommand)
sh -c 'echo $$; exec myCommand'
よりも構文的に優れている可能性があります 、しかし$$
を実行すると(
内)
、サブシェル自体ではなく、親シェルの PID を提供します。ただし、新しいコマンドの PID になるのはサブシェルの PID です。一部のシェルは、サブシェルの PID を見つけるための独自の移植不可能なメカニズムを提供します。できる これに使用します。特に、Bash 4 では、(echo $BASHPID; exec myCommand)
最後に、一部のシェルは、exec
のようにコマンドを実行する最適化を実行することに注意してください。 (つまり、最初にフォークするのをやめます) 後でシェルが何もする必要がないことがわかっている場合。実行する最後のコマンドになるといつでもこれを実行しようとするシェルもあれば、コマンドの前後に他のコマンドがない場合にのみ実行するシェルもあれば、まったく実行しないシェルもあります。その効果は、 exec
を書き忘れた場合 sh -c 'echo $$; myCommand'
を使用するだけです ときどき some で正しい PID を与える 一部のシステム シェル。そのような動作に依存することはお勧めしません。代わりに、常に exec
を含めることをお勧めします。
解決策 3:
コマンドを小さなスクリプトでラップする
#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file
解決策 4:
より簡単な解決策はわかりませんが、 $! を使用していません。十分ですか?他の人が言ったように、後で必要になった場合は、いつでも値を他の変数に割り当てることができます。
補足として、 ps からパイプする代わりに pgrep
を使用できます または pidof
.
解決策 5:
pid をファイルに登録した後、bash スクリプトから exec を使用します。
例:
引数 p1、p2、p3 で実行したい "forever.sh" という名前のスクリプトがあるとします
forever.sh ソースコード:
#!/bin/sh
while [ 1 -lt 2 ] ; do
logger "$0 running with parameters \"[email protected]\""
sleep 5
done
reaper.sh を作成します:
#!/bin/sh
echo $$ > /var/run/$1.pid
exec "[email protected]"
forever.sh から reaper.sh を実行:
./reaper.sh ./forever.sh p1 p2 p3 p4 &
forever.sh は、5 秒ごとに syslog に行を記録するだけです
/var/run/forever.sh.pid に pid があります
cat /var/run/forever.sh.pid
5780
そして、forever.sh は aok を実行しています。 syslog grep:
Nov 24 16:07:17 pinkpony cia: ./forever.sh running with parameters "p1 p2 p3 p4"
プロセス テーブルで確認できます:
ps axuwww|grep 'forever.sh p1' |grep -v grep
root 5780 0.0 0.0 4148 624 pts/7 S 16:07 0:00 /bin/sh ./forever.sh p1 p2 p3 p4