以下を実行するシェルスクリプトがあります。
export FOO=foo # step 1
/usr/bin/java my-server # step 2
シェルスクリプトは、ステップ2で開始されたプロセスのPIDを知る必要がある親プログラムによって開始されます。現在、これはexec
サーバーで実行コマンドを実行してシェルを手順2のコマンドに置き換えることによって行われます。したがって、シェルスクリプトのPIDとスクリプトを実行するプロセスは、「my-server」プロセスのPIDになります。
手順2で起動したサーバーをすばやく確認するには、このシェルスクリプトに別のコマンドを追加する必要があります。今私のプログラムは次のようになります。
export FOO=foo # step 1
exec /usr/bin/java my-server & # step 2
/usr/bin/java my-validation # step 3
上記の手順3を追加できますか?このアプローチの代替案は何ですか?
ベストアンサー1
他の回答とコメントを組み合わせて、以下を追加します。
exec your_command &
無意味。コマンドラインは非同期サブシェルで実行され、デフォルトでexec
は無視されます。- それはわずかな単純化する。私たちが言うなら
(コマンド1;コマンド2)&
その後、非同期サブシェルで実行されます(完了したら)。しかし、私たちが言うならcommand1
command2
command2
command1
(実装する コマンド1;コマンド2)&
これは実行されますが、実行されません。command1
command2
- それはわずかな単純化する。私たちが言うなら
- リダイレクトだけでなく、スクリプトで正しく設定されたコマンド
exec
に従うすべてのエントリは無視されます。exec
失敗しても、後続の行を実行せずにシェルが終了します(command exec ...
またはオプションbash
を使用して、失敗した場合にシェルが終了するのをexecfail
防ぐことができます)。exec
- inまたはまたはなど
exec
のサブシェルで実行されている場合、そのサブシェルのみが終了します。exec cmd &
exec cmd | cmd2
(exec cmd3)
- 確認コマンドでサーバープロセスのPIDを知る必要がある場合は、幸運ではないかもしれません。
そうでなく、サーバーが起動するまでverifyコマンドが自動的にしばらく待つ場合は、次のようにします。
export FOO=foo # step 1 /usr/bin/java my-validation & # step 1½ exec /usr/bin/java my-server # step 2
それ以外の場合はこれを行うことができます
export FOO=foo # step 1 (sleep 10; /usr/bin/java my-validation) & # step 1½ exec /usr/bin/java my-server # step 2
警告:「my-server」プロセスがすぐに終了すると、「my-validation」コマンドが実行される前にスクリプトが終了する可能性が高く、親プロセスは制御を取り戻して実行を再開します。親プロセスと「my-validation」コマンドの両方が同じ場所に出力を書き込むと、混在する可能性があります。
ただし、親プロセスがスクリプトが終了するのを待たないと、これは問題にならない可能性があります。