
さて、これはおそらく本当に愚かな質問です。そして私はシェルスクリプトを頻繁に作成しません。シェルスクリプトでは、バックグラウンドで3つのプロセスを順番に起動しようとしています。たとえば、次のようになります。
#!/bin/sh
PROCESS1 &
PROCESS2 &
PROCESS3 &
それが問題だ。示されたのと同じ順序でこれらのプロセスを開始する必要があります。さらに、PROCESS2のPIDは、PROCESS3にコマンドライン引数として渡される必要があります。これらのプロセスはすべて無限ループで実行され、3つの別々の端末で実行されると非常にスムーズに実行されます。
私は試した:
#!/bin/sh
PROCESS1 &
PROCESS2 &
PID_PROCESS2=$!
PROCESS3 ${PID_PROCESS2} &
PROCESS1 と PROCESS3 が起動しますが、PROCESS2 はエラーを出力せずに直ちに終了します。消えたばかりです。 ps コマンドは PROCESS2 のトレースを表示しません。 Print PID_PROCESS2は「p」値を返し、PROCESS3は「p」値を引数として使用してうまく機能します。私に問題や欠点がありますか?
重要な詳細
上記の例では、そのプロセスを呼び出すために完全修飾パスを使用しました。どちらもデフォルトのバイナリであり、同じディレクトリにあります。例えば、
#!/bin/sh /usr/bin/PROCESS1 &
psの出力は上記と同じです。
$ps | grep "/path/to/PROCESS" 10064 root 16536 S /path/to/PROCESS1 10066 root 11084 S /path/to/PROCESS3 10065
PROCESS2が開始されたが未知の理由で終了したことを明確に通知します。
PROCESS2は、一方向通信であるFIFO(Named Pipe)を介してPROCESS1と通信します。
解決策
#/bin/sh
/path/to/PROCESS1 &
/path/to/PROCESS2 & PROCESS2_PID=$!
export P2PID=${PROCESS2_PID}
sh -c "/path/to/PROCESS3 ${P2PID}"
これは、shがタスクを実行するための追加のプロセスを追加するようです。
$ps | grep "/path/to/PROCESS"
10174 root 16536 R /path/to/PROCESS1
10175 root 71720 S /path/to/PROCESS2
10177 root 27772 S sh -c /path/to/PROCESS3 10175
10076 root 11084 S /path/to/PROCESS3 100175
しかし、なぜこのようなことが起こるのかまだわかりません。この場合、どのような「魔法」が起こっているのかを提案できる人はいますか?
答え1
あなたの説明によると、PROCESS2が終了する根本的なバグがあるようです。 3つのプロセスで説明するものをモデル化する場合は、バックグラウンドで3つのプロセスを実行してから、プロセス2のPIDをキャプチャしてプロセス3に渡すと、基本的に期待どおりに機能します。
はい
サンプルスクリプト$ cat runny.bash
#!/bin/bash
proc3func() {
echo $1
sleep 7 &
}
sleep 9 &
sleep 8 &
PID2=$!
proc3func ${PID2} &
実行例
$ ./runny.bash ; sleep 2; ps -eaf
4279
UID PID PPID C STIME TTY TIME CMD
...
vagrant 4278 1 0 20:21 pts/1 00:00:00 sleep 9
vagrant 4279 1 0 20:21 pts/1 00:00:00 sleep 8
vagrant 4282 1 0 20:21 pts/1 00:00:00 sleep 7
上記の出力では、PID 4279が画面にエコーされ、後続の出力にps -eaf
3つのプロセスが表示されることがわかります。
デバッグ
set -x
スクリプトの実行時に実行されるコマンドに従うか、次のように実行できるようにすることをお勧めします。
$ bash -x ./runny.bash
+ PID2=4612
+ sleep 9
+ sleep 8
+ proc3func 4612
+ echo 4612
4612
+ sleep 7