要求に応じて出力を新しいファイルに動的にリダイレクトするツールはありますか


8

現在、監視ツールの出力をファイルにリダイレクトしていますが、このツールを停止せずに、(キーバインディングを使用して)要求に応じてこの出力を新しいファイルにリダイレクトします。

何かのようなもの

monitor_program | handle_stdout

どこでhandle_stdout、ログを特定のポイントに配置する新しいファイルを定義できます。

私はそれを簡単に書くことができることを知っていますが、すでにこれを可能にするツールがあるかどうか疑問に思っています。


おそらくlogrotate、monitor_programの動作に応じて、手動でカスタム構成ファイルを使用して実行できますが、それはややハックです。
Ulrich Schwarz

あなたの編集は実際には質問に対する答えのようです。その場合は、回答として投稿してください(自己回答が推奨されます)。質問から回答を削除してください。

回答:


9

名前付きパイプをお勧めします。

  1. パイプを作成するmkfifo p( 'p'でない場合は、好きな名前を付けてください)

  2. パイプから読み取り、好きな場所に書き込む「リーダー」スクリプトを作成する

  3. 監視プログラムにログを名前付きパイプに書き込むように指示する

名前付きパイプ「p」から読み取り、インデックス付きの「mylog」ファイルにデータを書き込むサンプルリーダースクリプトを次に示します。

#!/bin/sh

INDEX=0

switchlog() {
  read INDEX < newindex
  echo now writing to "mylog.$INDEX"
}

trap switchlog USR1

while :
do
  cat p >> mylog."$INDEX"
done

2
ログを切り替える信号として、リーダースクリプト内の信号(たとえば、USR1)をトラップすることもできます。
ジェフシャラー

これは私が必要とするものになり始めます...しかし、リーダースクリプトは、私のバインディングに基づいて出力を変更できるはずです。そして、潜在的に(これはオプションですが、でも、シーケンシャルログ名を持つことはいいと思い)を使用する新しいファイル名のために私に尋ねる
トレビノ

サンプルスクリプトを編集して、kill -USR1を使用したログ切り替えの例を示しました。新しい番号を「newindex」ファイルにエコーして取得します。
ジェフシャラー

1
別のアイデア-実行中の「リーダー」スクリプト用にウィンドウを開いたままにした場合、USR1の代わりに「INT」をトラップし、そのウィンドウでControl-Cを押すだけで、新しいログファイル名を通知できます。
ジェフシャラー

1
なぜreadprintf代わりにcat <p >> mylog."$INDEX"
ワイルドカード2016年

7

ここでSIGQUIT(Ctrl+\)を使用してSIGINTのアイデアを構築し、まだCtrl+C全体を停止するために使用できます。

(trap '' QUIT; monitor_command) | (
   trap : QUIT
   ulimit -c 0 # prevent core dump so SIGQUIT behaves like SIGINT
               # for cat
   n=0; while n=$((n+1)); file=output.$n.log; do
     printf 'Outputting to "%s"\n' "$file"
     cat > "$file"
   done)

それはcatあなたのシェルの組み込みではないことを前提としています(そのため、を押すと中断されますCtrl+\)。

あなたのアプローチと同様に、SIGQUITが間違ったタイミングで(書き込みシステムコールで)配信され、一部のデータが失われる可能性があることに注意してください。


1

less保存先sのファイル名を入力して、そこからを使用して、そこから保存することができますEnter。からlessからすべての行をファイルに書き込むにはどうすればよいですか?


残念ながら、一度ログファイルを設定すると、新しいログファイルを再定義することはできなくなります。また、一度ログをクリアすることはできません。だから...良い出発点(ありがとう)ですが、まだ十分ではありません。
トレビニョ2016年

0

あなたの「リクエスト」についてもっと知らなければ、答えることは実際には不可能です。ファイルサイズまたは間隔に基づいている場合は、rotatelogs(Apache httpdにバンドルされているはず)が機能します。


申し訳ありませんが、明示的には言っていません。ログ名を変更できるキーバインドを想定しています。
トレビニョ2016年

0

Jeff Schallerの回答のおかげで、私はこのようなものになりましたreader.sh

#!/bin/sh

INDEX=0
LOGNAME="$INDEX.log"

switchlog() {
  local custom_name
  read -p "Add log name: " custom_name
  INDEX=$((INDEX+1))
  LOGNAME="$(printf "%03d" $INDEX).$custom_name.log"
  echo now writing to $LOGNAME
}

trap switchlog INT
switchlog

while :
do
  read foo < p
  printf "%s\n" "$foo" >> "$LOGNAME"
done

次に、で名前付きパイプを作成し、とが実行されmkfifo pている2つのターミナルを使用します。次に、+ を使用してリーダーを停止し、新しいログを設定して、新しい名前を入力します。+ 通常どおり、停止して終了します。monitor_program > preader.shCtrlCCtrlZ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.