sh [重複]に 'exec &> >(tee -a "$LOG_FILE")' を適用します。

sh [重複]に 'exec &> >(tee -a "$LOG_FILE")' を適用します。

これからbash

exec &> >(tee -a "$LOG_FILE")

ロギング(書き込み)中に出力が端末に表示されるように&stderrをリダイレクトしますが、プロセスオーバーライドを使用します。stdouttee$LOG_FILEsh

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必要がないことを正しく指摘しました。作者がついにパイプを閉じると、とにかく致命的になるからです。teeSIGPIPE

$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それをサポートしていないいくつかの実装があります(最も目立つ)。バラよりshshdashkornシェルから返品ステータスをキャプチャし、同時にteeを使用する方法は?他の方法の場合。

sh1980年代には通常Bourneシェル(Thompsonシェルを継承)でしたが、今日はksh88(Bourneシェルの派生)のサブセットに基づく標準のPOSIX言語用インタプリタの1つまたは別の実装shです。sh、Bourneシェルではありません。プロセスの置き換えはksh(元のksh86)で行われますが、POSIXはまだ指定されておらず、shAlmquistシェル(元のBourneシェルのクローン)またはForsythシェル(元はBourneシェルのクローンですがpdksh / mkshを含む)から派生します。 Kornシェル)。 .ksh88をサポートしていないシステムでも使用できません/dev/fd/n

関連情報