teeコマンドは標準入力を標準出力に書き出すだけではなく、引数にした複数のファイルにも書き出すことができます。teeコマンドは、別のコマンドの実行結果をファイル書き出すだけではなく標準出力でも確認したいときや、一つのコマンドの実行結果を使用して、複数の処理に分岐させたいときに利用できます。
目次
teeコマンドの利用例
実行結果を同時にファイルと標準出力に出力
teeコマンドは、パイプを用いて、別のコマンドの実行結果をファイルと標準出力に出力することができます。ただし、teeコマンドで指定したファイルは存在しない場合は作成され、存在する場合は上書きされます。
コマンド例と実行結果
1 2 3 4 5 6 7 8 |
$echo 'tee test' | tee file1 file2 tee test $ $cat file1 tee test $ $cat file2 tee test |
teeコマンドで出力するファイルに追記で出力
(-aオプション)
-aオプションを用いると、teeコマンドで指定したファイルを上書きではなく、追記で出力していくことができます。ログファイルなどに利用する場合に便利なオプションになります。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 |
$cat file1 tee test $ $echo 'tee -a option test' | tee -a file1 tee -a option test $ $cat file1 tee test tee -a option test |
teeコマンドのテクニック
標準エラー出力もteeコマンドで出力
リダイレクトの構文は
1 |
[n]>word |
になり、nは数字で、ファイル記述子(ファイルディスクリプタ,file descriptor)を表します。
ファイル記述子は基本的に、0が標準入力、1が標準出力、2が標準エラー出力を表します。
wordはファイルを表します。出力の場合、nが省略された場合は1が指定されます。
また、リダイレクトの複製の構文は
1 |
[n]>&word |
で、この場合のwordは数字でファイル記述子を表します。これはwordのファイル記述子の出力先が、nのファイル記述子の出力先と同じになります。
teeコマンドで標準エラーも同時に出力したい場合は、teeコマンドで通す前のコマンドに対して、標準エラー出力を標準出力にするリダイレクトを行います。
つまり、リダイレクトの方法は以下のようになります。
1 |
command 2>&1 |
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$bash print.sh | tee file This is stderr This is stdout $ $cat file This is stdout $ $bash print.sh 2>&1 | tee file This is stdout This is stderr $ $cat file This is stdout This is stderr |
print.sh
1 2 3 4 5 |
#/bin/bash echo 'This is stdout' echo 'This is stderr' >&2 |
プロセス置換を用いてコマンドを処理
プロセス置換(Process Substitution)は、Bashの機能でプロセスを入力ファイルや出力ファイルのように利用できます。プロセス置換で用いたプロセスは非同期で実行されます。プロセス置換の構文は以下のようになります。
1 2 |
<(list) >(list) |
このプロセス置換とteeコマンドを組み合わせると大きなファイルを何度も読み込むことなく、複数の処理を行うことができます。
ここの例では、ファイルの圧縮と圧縮前のファイルのいくつかのチェックサムを行います。また、チェックサムや圧縮ができているかの簡単なチェックも行っています。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 |
$cat archive.tar | tee >(sha1sum > archive_sha1sum) >(md5sum > archive_md5sum) | gzip > archive.tar.gz $ls archive.tar archive.tar.gz archive_md5sum archive_sha1sum $ $cat archive.tar | md5sum -c archive_md5sum -: 完了 $cat archive.tar | sha1sum -c archive_sha1sum -: 完了 $gzip -t -v archive.tar.gz archive.tar.gz: OK |
execコマンドでファイルディスクリプタを変換
execコマンドは組み込みコマンドで、コマンドが指定された場合、新しいプロセスを作成せずに現在のシェルに置き換えてコマンドを実行します。
しかし、execコマンドでコマンドを指定せずにリダイレクトのみを行うと現在のシェルのリダイレクトの設定を変更できます。これを用いるとシェルスクリプトで実行結果のログやエラーのログを取りやすくなります。
tee_log.sh
1 2 3 4 5 6 7 |
#/bin/bash exec 1> >(tee stdout.log) exec 2> >(tee stderr.log >&2) echo 'This is stdout' echo 'This is stderr' >&2 |
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 |
$bash tee_log.sh $This is stdout This is stderr $cat stdout.log This is stdout $ $cat stderr.log This is stderr |
このログの取り方の欠点としては、プロセス置換で処理するコマンドがバックグラウンドで動作し、シェルスクリプトの終了が分かりずらくなるかもしれません。