シェル操作 初級

tee コマンド入門 - 出力を画面とファイルに同時に書き込む

teeコマンドを使って標準出力をファイルに保存しながらパイプラインに流し続ける方法を学ぶ

コマンドの出力を確認しながらファイルにも保存したい、という場面はよくあります。 > を使うと画面には何も表示されず、| だけだとファイルに保存できません。 tee コマンドはその両方を同時にこなす「T字型分岐」の役割を果たします。

tee コマンドとは

tee は標準入力から受け取ったデータを、標準出力とファイルの両方に書き出すコマンドです。 水道管の「T字継手」のように、データの流れを二方向に分岐させます。

コマンド → tee → 画面(標準出力)
                ↓
               ファイル

基本的な使い方

出力を画面に表示しながらファイルにも保存する

ls -la | tee output.txt

このコマンドを実行すると、ls -la の結果が画面に表示され、同時に output.txt にも書き込まれます。

# ファイルの内容を確認
cat output.txt

パイプラインの途中でログを取る

tee の真価はパイプラインの中間で使うときに発揮されます。

cat /var/log/syslog | grep "error" | tee errors.txt | wc -l

この例では:

  1. syslog の内容を取得
  2. “error” を含む行を抽出
  3. tee で errors.txt に保存しつつ、次のコマンドにも流す
  4. wc -l で行数を数えて画面に表示

ファイルにエラーログを保存しながら、その件数も確認できます。

ファイルに追記する(上書きしない)

デフォルトでは tee はファイルを上書きします。追記したい場合は -a オプションを使います。

echo "1回目のログ" | tee log.txt
echo "2回目のログ" | tee -a log.txt

cat log.txt
# 出力:
# 1回目のログ
# 2回目のログ

-a を付けないと「2回目のログ」だけが残ります。

複数のファイルに同時に書き込む

tee にはファイルをいくつでも指定できます。

echo "テストデータ" | tee file1.txt file2.txt file3.txt

3つのファイルすべてに同じ内容が書き込まれ、画面にも表示されます。

sudo と組み合わせて管理者権限でファイルを書き込む

root 権限が必要なファイルに書き込む際に tee がよく使われます。

# これはエラーになる(リダイレクトは sudo の外で処理されるため)
sudo echo "設定内容" > /etc/config.conf

# tee を使えば正しく書き込める
echo "設定内容" | sudo tee /etc/config.conf

# 追記の場合
echo "追加設定" | sudo tee -a /etc/config.conf

sudo tee とすることで、tee コマンド自体が root 権限で実行されるため、書き込みが成功します。

標準エラー出力も一緒にファイルに保存する

エラーメッセージ(標準エラー出力)もファイルに残したい場合は、リダイレクトと組み合わせます。

# 標準出力と標準エラーをまとめてファイルに保存
make 2>&1 | tee build.log

2>&1 は標準エラー出力(2)を標準出力(1)と同じ場所に向けるリダイレクトです。 これにより、エラーも含めたすべての出力が build.log に保存されます。

実用例:スクリプトのログ取り

スクリプトの実行内容をログファイルに記録しながら画面にも表示する。

#!/bin/bash
LOG_FILE="script_$(date +%Y%m%d).log"

echo "処理を開始します..." | tee "$LOG_FILE"
ls /tmp | tee -a "$LOG_FILE"
echo "処理が完了しました。" | tee -a "$LOG_FILE"

echo "ログは ${LOG_FILE} に保存されました。"

練習問題

問題1

uptime コマンドの出力を画面に表示しながら、uptime.txt というファイルにも保存するコマンドを書いてください。

問題2

/etc/passwd の最初の5行を取得し、その内容を users.txt に保存しつつ、さらに : で区切られた最初のフィールド(ユーザー名)だけを画面に表示するコマンドを一行で書いてください。

問題3

以下のコマンドを実行した後、log.txt の内容はどうなりますか?

echo "A" | tee log.txt
echo "B" | tee log.txt
echo "C" | tee -a log.txt

答え

問題1の答え

uptime | tee uptime.txt

問題2の答え

head -n 5 /etc/passwd | tee users.txt | cut -d: -f1
  • head -n 5 /etc/passwd:最初の5行を取得
  • tee users.txt:users.txt にその5行を保存し、パイプラインに流し続ける
  • cut -d: -f1:: 区切りの1番目のフィールド(ユーザー名)だけを画面に出力

問題3の答え

log.txt の内容は次のようになります:

B
C
  • echo "A" | tee log.txt → log.txt に “A” を書き込む(上書き)
  • echo "B" | tee log.txt → log.txt に “B” を書き込む(上書き):この時点で “A” は消える
  • echo "C" | tee -a log.txt → -a オプションで “C” を 追記

最終的に “B” と “C” の2行が残ります。


まとめ

コマンド例動作
cmd | tee file.txt画面表示 + ファイルに上書き保存
cmd | tee -a file.txt画面表示 + ファイルに追記
cmd | tee f1.txt f2.txt画面表示 + 複数ファイルに保存
cmd | sudo tee /path/to/fileroot 権限が必要なファイルへの書き込み
cmd 2>&1 | tee log.txtエラーも含めてすべてをファイルに保存

tee はシンプルながら、パイプラインのデバッグや、処理結果の記録に非常に便利なコマンドです。 ぜひ日々の作業に取り入れてみてください。