コマンドを並列に実行し、特定の出力を待ちます。

コマンドを並列に実行し、特定の出力を待ちます。

私は初めてbashスクリプトに触れました。

  1. コマンドを並列に実行します(例:Nodejs Webアプリケーションの実行)。コマンドの出力は通常どおりコンソールに書き込む必要があります。
  2. 出力に特定の文字列が表示されるのを待ちます(例:「DBが初期化されました」)。
  3. 次に、別のコマンド(たとえば、データベースデータを生成するコマンドなど)を実行します。
  4. 次に、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 -qteeこれにより、終了するcatまでパイプから読み取ることが防止されます。npmtee

非同期で実行する必要はありません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{ ... }使用できます。

関連情報