起動中の一部のクラウドシステムでは、特定のファイル、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))
デフォルトのプロセス交換の最初のものは、tee
STDOUT / STDERRをターミナルと入れ子になったプロセス交換に転送してtee
内部でファイルに内容を保存し、パイプライン出力をSTDIN/tmp/box-setup.log
に送信するために使用されます。logger
答え2
Bashスクリプトの実行中にコンソールが空になったので、私は完全に目が遠かった。
別の方法で問題を解決したい場合があります。バックグラウンドでbashスクリプトを実行してから実行しless /tmp/box-setup.log
、Fキーを押して表示中のファイルに行が追加されたとき(たとえばtail -f
)画面を更新し続けます。
バックグラウンドでスクリプトを実行できない場合は、1つのSSH接続で複数のセッションを使用またはtmux
多重化してください。他のシェルでも同じコマンドを使用してください。screen
less
元の質問:
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)
標準出力と標準エラーがマージされます。順序を維持するために分離することはできません。これは一般に望ましい。とにかく、すべて同じ場所(ターミナルなど)に行くことは重要ではありません。