私は初めてbashスクリプトに触れました。
- コマンドを並列に実行します(例:Nodejs Webアプリケーションの実行)。コマンドの出力は通常どおりコンソールに書き込む必要があります。
- 出力に特定の文字列が表示されるのを待ちます(例:「DBが初期化されました」)。
- 次に、別のコマンド(たとえば、データベースデータを生成するコマンドなど)を実行します。
- 次に、1.のコマンドが終了するまで待ちます。
以下はwaitの現在のスクリプトですが、sleep
もちろんこれは回避策です。
# parallel command
npm run start &
# wait for specific output
sleep 15s
# do something
node_modules/.bin/knex seed:run
# wait for parallel command to exit
wait
私が一つ見つけたエマルジョンしかし、並列に実行されたコマンドの出力はコンソールに印刷されないようです。
背景:このスクリプトは、nodejsイメージのalpineバリアントに基づくdockerイメージのエントリポイントです。
答え1
これを達成する方法の1つは次のとおりです。
npm run start |
tee /dev/tty | {
grep -q "DB initialized" && node_modules/.bin/knex seed:run
cat >/dev/null
}
tee /dev/tty
出力をコピーしてnpm
端末に送信し、後続のコマンドにパイプします。
grep -q
状態に一致する最初の項目で自動的に終了します0
。これにより、「AND」リスト(node_modules/.bin/knex seed:run
)の次のコマンドがトリガーされます。
cat /dev/null
パイプを開け続けるのですか?終了すると、パイプにさらにデータを書き込もうとし、次に終了中にSIGPIPE信号を受信しますgrep -q
。tee
これにより、終了するcat
までパイプから読み取ることが防止されます。npm
tee
非同期で実行する必要はありませんnpm
。パイプラインのすべてのコンポーネントが同時に実行されます。唯一確認する必要があるのは、遅いコンポーネントが完了する前にそのコンポーネントが終了しないことです。
このコードスニペットは、/dev/tty
制御端末なしでプロセスコンテキストで実行されている場合は機能しない可能性があります。/dev/fd/n
システムのフォームでも標準ストリームにアクセスできると仮定すると、別のオプションは次のとおりです。
npm run start | {
tee /dev/fd/9 | {
grep -q "DB initialized" && node_modules/.bin/knex seed:run
cat >/dev/null
}
} 9>&1
9
選択したファイル記述子は、パイプ全体の標準出力が関連付けられているファイルのコピーとして生成され、外部リストのすべてのコマンド/dev/fd/9
で{ ... }
使用できます。