grepを使用して出力をフィルタリングするために、execとパイプを使用してシェルスクリプトで信号を処理します。

grepを使用して出力をフィルタリングするために、execとパイプを使用してシェルスクリプトで信号を処理します。

起動時に無駄なメッセージをたくさん出力するコンテナ化されたアプリケーションをデプロイしています(同じメッセージが100万回表示され、何も変更されません)。このメッセージはアプリケーション構成によって抑制できず、アプリケーション開発は私の制御範囲外です。これにより、ロギングインフラストラクチャに迷惑をかけ、問題が急増する可能性があります。ログ記録インフラストラクチャからのメッセージはログを表示したときにのみフィルタリングでき、コンテナランタイムからログ記録ストレージバックエンドにログを渡すときはフィルタリングできません。

したがって、私の意図は、foo bar bazアプリケーションの外部のコンテナエントリポイントの内部を使用してこのメ​​ッセージを抑制することです(次の例)。grepこれまで私が試したことは次のとおりです。

#!/bin/bash
set -euxo pipefail

exec myapp --some parameter | grep --line-buffered -v "foo bar baz"

ただし、これはPID 1に代わるものではないため、myapp --some parameter信号はSIGTERM正しいプロセスに渡されません。

$> docker exec -it ep-test ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.0  18384  3008 pts/0    Ss+  16:54   0:00 /bin/bash /entrypoint
root         7  0.0  0.0   4540   836 pts/0    S+   16:54   0:00 myapp --some parameter
root         8  0.0  0.0  11472   964 pts/0    S+   16:54   0:00 grep --line-buffered -v "foo bar baz"
root         9  0.0  0.0  34412  2668 pts/1    Rs+  16:54   0:00 ps aux

execに減らすと、exec myapp --some parameterPID 1が正しく置き換えられます(ただし、出力は必要に応じてフィルタリングされません)。

$> docker exec -it ep-test ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.2  0.0   4540   768 pts/0    Ss+  16:55   0:00 myapp --some parameter
root         7  0.0  0.0  34412  2796 pts/1    Rs+  16:55   0:00 ps aux

アプリケーションをきれいに終了するにはSIGTERM(および他の既知の信号)をに渡すことが重要ですmyapp。私が知っている限り、これを達成する最も簡単な方法は、PID 1をexec

myappgrepだから私の質問は、コンテナに送信された信号がに転送/転送されることを確認しながらwithの出力をフィルタリングする簡単な方法はありますかmyapp

答え1

通常のパイプを使用しないように、grepでbashという名前のパイプ(fifo)を試すことができます。この構文は>(cmd)fifoを生成し、cmdfifoを標準入力として実行し、コマンドラインでfifoの名前を置き換えるので、/dev/fd/63アプリコマンドのstdoutを対応するfifoに送信できます(例:)>

exec myapp --some parameter > >(grep --line-buffered -v "foo bar baz")

スペースに注意してください> >()

関連情報