1. ホーム
  2. バッシュ

[解決済み】bashスクリプト自身からstdoutのCOPYをログファイルにリダイレクトする。

2022-04-02 05:55:50

質問

私は、以下の方法を知っています。 標準出力をリダイレクトする をファイルに保存します。

exec > foo.log
echo test

これは、'test' を foo.log ファイルに入れることになります。

今度は ログファイルへの出力をリダイレクトし、かつ標準出力に残す。

つまり、スクリプトの外から簡単に実行できるのです。

script | tee foo.log

しかし、私はそれをスクリプト自体の中で宣言したいのです。

試しに

exec | tee foo.log

が、うまくいかなかった。

どうすればいいですか?

#!/usr/bin/env bash

# Redirect stdout ( > ) into a named pipe ( >() ) running "tee"
exec > >(tee -i logfile.txt)

# Without this, only stdout would be captured - i.e. your
# log file would not contain any error messages.
# SEE (and upvote) the answer by Adam Spiers, which keeps STDERR
# as a separate stream - I did not want to steal from him by simply
# adding his answer to mine.
exec 2>&1

echo "foo"
echo "bar" >&2

なお、これは bash ではなく sh . でスクリプトを起動した場合 sh myscript.sh というエラーが発生します。 syntax error near unexpected token '>' .

シグナルトラップを扱う場合は tee -i オプションを使用すると、シグナルが発生したときに出力が乱れるのを防ぐことができます。(JamesThomasMoon1979さん、コメントありがとうございました)。


パイプに書き込むかターミナルに書き込むかで出力が変わるツール( ls 例えば、カラーやカラム化された出力を使用する場合、上記の構成はパイプに出力することを意味するものとして検出されます。

色付け/列挙を強制するオプションがあります (例. ls -C --color=always ). なお、この場合、カラーコードがログファイルにも書き込まれるため 少ない を読み取ることができます。