stdoutとstderrをファイル、syslog、および端末に送信する

stdoutとstderrをファイル、syslog、および端末に送信する

起動中の一部のクラウドシステムでは、特定のファイル、syslog、およびターミナル/コンソールにログインしようとします。

マイコンピュータの設定/クラウド初期化スクリプトの上部には次のものがあります。

#!/bin/bash
exec &> >(tee "/tmp/box-setup.log" | logger -t box-setup)
apt-get install -y some-package

これは、出力をファイルとsyslogに送信するのに有効ですが、出力を端末にパイプすることはありません。

通常、リモートコンソールでデバッグしない限り、ターミナル出力がないことは大きな問題ではありません。これが発生した場合、bashスクリプトの実行中にコンソールが空になったため、完全に目が遠くなりました。

bashリダイレクトや他の手段を使用してすべての出力(stdoutとstderr)をファイル、syslog、および端末に同時にパイプする簡単な方法はありますか?

Ubuntu 16.04を実行しています。

答え1

tee次のように、入れ子になったプロセスの置き換えと1つを追加します。

exec &> >(tee >(tee "/tmp/box-setup.log" | logger -t box-setup))

デフォルトのプロセス交換の最初のものは、teeSTDOUT / STDERRをターミナルと入れ子になったプロセス交換に転送してtee内部でファイルに内容を保存し、パイプライン出力をSTDIN/tmp/box-setup.logに送信するために使用されます。logger

答え2

Bashスクリプトの実行中にコンソールが空になったので、私は完全に目が遠かった。

別の方法で問題を解決したい場合があります。バックグラウンドでbashスクリプトを実行してから実行しless /tmp/box-setup.log、Fキーを押して表示中のファイルに行が追加されたとき(たとえばtail -f)画面を更新し続けます。

バックグラウンドでスクリプトを実行できない場合は、1つのSSH接続で複数のセッションを使用またはtmux多重化してください。他のシェルでも同じコマンドを使用してください。screenless


元の質問:

tee複数の宛先にコピーできます。特殊ファイルを使用して、それらの1つを端末に設定します/dev/tty。私はそれが常に現在のプロセスの制御ttyを参照していると思います。あるいは、stderrがまだシェルのstderrに接続されているので、/dev/stderrより良いかもしれません。tee(これにより、&> / dev / nullを使用してスクリプトをサイレントできます)。

exec &> >(tee /dev/stderr "/tmp/box-setup.log" | logger -t box-setup)

ところで、これはDanbyと同じです(tee /dev/stderr | tee "/tmp/box-setup.log" | logger ...)

tee一部のファイル記述子レプリカは、標準エラーではなく元のスクリプトの標準出力を提供するために使用できます。

答え3

/dev/stderr(必要なものを)出力としてに追加するだけですtee

exec &> >(tee /dev/stderr "/tmp/box-setup.log" | logger -t box-setup)

標準出力と標準エラーがマージされます。順序を維持するために分離することはできません。これは一般に望ましい。とにかく、すべて同じ場所(ターミナルなど)に行くことは重要ではありません。

関連情報