GNU/Linux >> Linux の 問題 >  >> Linux

受信しているアプリケーションを強制終了せずに Linux の tee コマンドを終了する方法

teeのとき 終了すると、さらに出力を書き込もうとするまで、コマンドを実行し続けます。次に、リーダーのないパイプに書き込もうとすると、SIGPIPE (ほとんどのシステムでは 13) を取得します。

スクリプトを変更して SIGPIPE をトラップし、適切なアクション (出力の書き込みを停止するなど) を実行すると、tee が終了した後もスクリプトを続行できるはずです。

tee を殺すのではなく、いっそのこと 全然 logrotate を使用 copytruncate で 簡単にするためのオプションです。

logrotate(8) を引用するには :

<ブロック引用>

copytruncate

古いログ ファイルを移動し、必要に応じて新しいログ ファイルを作成するのではなく、コピーの作成後に元のログ ファイルをその場で切り捨てます。一部のプログラムにログファイルを閉じるように指示できない場合に使用でき、以前のログファイルに永遠に書き込み (追加) し続ける可能性があります。ファイルのコピーと切り捨ての間には非常に短いタイム スライスがあるため、一部のログ データが失われる可能性があることに注意してください。このオプションを使用すると、古いログ ファイルがそのまま残るため、作成オプションは無効になります。


「理由」の説明

要するに:書き込みが失敗 しなかった プログラムを終了させると(デフォルトで)、混乱が生じます。 find . | head -n 10 を検討してください -- find は必要ありません head 以降、残りのハードドライブをスキャンして実行を続ける すでに必要な 10 行を取得して処理を進めています。

より良い方法:ロガー内をローテーション

tee を使用しない次の例を検討してください。 実例として、

#!/usr/bin/env bash

file=${1:-debug.log}                     # filename as 1st argument
max_size=${2:-100000}                    # max size as 2nd argument
size=$(stat --format=%s -- "$file") || exit  # Use GNU stat to retrieve size
exec >>"$file"                           # Open file for append

while IFS= read -r line; do              # read a line from stdin
  size=$(( size + ${#line} + 1 ))        # add line's length + 1 to our counter
  if (( size > max_size )); then         # and if it exceeds our maximum...
    mv -- "$file" "$file.old"            # ...rename the file away...
    exec >"$file"                        # ...and reopen a new file as stdout
    size=0                               # ...resetting our size counter
  fi
  printf '%s\n' "$line"                  # regardless, append to our current stdout
done

次のように実行する場合:

/mnt/apps/start.sh 2>&1 | above-script /tmp/nginx/debug_log

...これは /tmp/nginx/debug_log に追加することから始まります 、ファイルの名前を /tmp/nginx/debug_log.old に変更します 100KB を超えるコンテンツが存在する場合。ロガー自体がローテーションを行っているため、パイプの破損やエラーはなく、ローテーションが発生してもデータ損失ウィンドウは発生しません。すべての行が 1 つのファイルまたは別のファイルに書き込まれます。

もちろん、これをネイティブの bash に実装するのは効率的ではありませんが、上記はわかりやすい例です。 上記のロジックを実装するプログラムは数多くあります。考慮事項:

  • svlogd 、Runit スイートのサービス ロガーです。
  • s6-log 、積極的に維持されている skanet スイートの代替品です。
  • multilog DJB Daemontools から、プロセス監視および監視ツールのこのファミリーの祖父です。

Linux
  1. Linuxでコマンド出力をファイルに保存する方法

  2. Linuxでコマンドラインからファイルとディレクトリを削除する方法

  3. SCP Linuxコマンド–リモートからローカルへのSSHファイル転送方法

  1. Linuxファイルコマンド:Linuxでファイルタイプを決定する方法

  2. Linuxでコマンドラインからファイルを分割して結合する方法

  3. ターミナルウィンドウからLinuxでファイルを作成するには?

  1. Linuxでファイルまたはディレクトリを削除(削除)する方法

  2. Linuxコマンドラインからtar.gzファイルを抽出または解凍する方法

  3. Linuxでmd5sumコマンドを使用する方法