これからbash
:
exec &> >(tee -a "$LOG_FILE")
ロギング(書き込み)中に出力が端末に表示されるように&stderr
をリダイレクトしますが、プロセスオーバーライドを使用します。stdout
tee
$LOG_FILE
sh
sh を使用してスクリプトを実行する場合:
sh script
私は得る:
syntax error near unexpected token `>'
同じ結果を得るには、次のことをsh
試しました。
exec 2>&1 | tee -a "$LOG_FILE"
しかし、私は何も書いていないことを知り、$LOG_FILE
代わりに次のものを使用する必要がありました。
exec > "$LOG_FILE" 2>&1
これによりログがファイルに書き込まれますが、スクリプトの実行時に出力は表示されません。
どんなアイデアがありますか?
許可された回答では、次を使用してください。
mkfifo "$HOME/.pipe.$$"
インラインコードは許可されていますが、ブロック内では許可されていないため、提案された回答のヘルプ/追加
答え1
ここに
#!/bin/sh
#
LOG_FILE=/tmp/log_file # Demonstration target
# Set up the redirection to `tee`
mkfifo "$HOME/.pipe.$$"
tee -a "$LOG_FILE" <"$HOME/.pipe.$$" &
exec 1>"$HOME/.pipe.$$" 2>&1
rm -f "$HOME/.pipe.$$"
# Using the redirection
echo hello
date
echo STDERR >&2
exit 0
変換の鍵は、パイプライン生成、リダイレクト生成を中心に行われます。標準入力fortee
とリダイレクト標準出力そして標準エラー残りのプロセスのために。真ん中にはtee
自分自身の呼び出しがあります。
tee -a "$LOG_FILE" <"$HOME/.pipe.$$" &
ここでは、"$LOG_FILE"
作成したばかりのパイプを読み込んで作成(追加)し、通常どおりバックグラウンド&
で実行されるコマンドを追跡します。パイプが両方(作成者とリーダー)で開くと、ファイルシステムから削除できます。パイプはまだ存在し、両側で完了するまで使用できますが、名前でアクセスできなくなります。
中初期編集このスクリプトは、スクリプトの最後で終了する準備をするために、コマンドのPIDをtee
変数にキャプチャします。しかし、誰かが私にスクリプトの最後でプロセスを終了する$tpid
必要がないことを正しく指摘しました。作者がついにパイプを閉じると、とにかく致命的になるからです。tee
SIGPIPE
$LOG_FILE
プロダクションコードでは、安全な場所で作成すると想定しています。/tmp
残りのコードが機能するようにプレースホルダに入れました。
答え2
ただし:
#! /bin/sh -
LOG_FILE=/var/log/myscript.log
{
the whole script here:
...
} 2>&1 | tee -a -- "$LOGFILE"
または:
#! /bin/sh -
LOG_FILE=/var/log/myscript.log
main() {
the whole script here:
...
}
main "$@" 2>&1 | tee -a -- "$LOGFILE"
スクリプト終了ステータスはtee
's' です。これはオプションを使用して解決できますが、このオプションが標準の次のバージョンで標準になってもpipefail
それをサポートしていないいくつかの実装があります(最も目立つ)。バラよりsh
sh
dash
kornシェルから返品ステータスをキャプチャし、同時にteeを使用する方法は?他の方法の場合。
sh
1980年代には通常Bourneシェル(Thompsonシェルを継承)でしたが、今日はksh88(Bourneシェルの派生)のサブセットに基づく標準のPOSIX言語用インタプリタの1つまたは別の実装sh
です。sh
、Bourneシェルではありません。プロセスの置き換えはksh(元のksh86)で行われますが、POSIXはまだ指定されておらず、sh
Almquistシェル(元のBourneシェルのクローン)またはForsythシェル(元はBourneシェルのクローンですがpdksh / mkshを含む)から派生します。 Kornシェル)。 .ksh88をサポートしていないシステムでも使用できません/dev/fd/n
。