「ティー」の目的は何ですか?


90

tee私が今まで見た使用法はすべてそのようなものでした:

 do_something | tee -a logfile

または:

do_something_else | tee logfile

されteeますが、シェルのパイプリダイレクトと同じことを行うことができます知っていないもののために発明しましたか?といった:

do_something >> logfile

または:

do_something_else > logfile

これは実質的に同じであり、入力するキーボードのヒットが少なくなります。見えない隠し機能は何teeですか?


62
マニュアルページの最初の行「...そして標準出力とファイルに書き込む」でこれに答えられなかったのはどうしてですか?答えは興味深いものですが、パイプがどのように役立つかについて広くお話しすることは、このQ が広すぎるように見えることを補強するだけあり、おそらく閉じられるべきでした。
Xen2050

3
@ Xen2050質問は、あまりに広範に答えても非難されません。質問は非常に具体的であり、現在の最高評価の回答も同様です。
ジョンベントレー

1
@JonBentleyの質問は、「適切な答えを特定するのに十分な詳細を伴う特定の問題」のように聞こえません(閉じるダイアログが読むように)。これは、このような音を行います。「あなたの質問は、書籍全体で答えられることができれば、あるいは多くの有効な解答(しかしかを判断する方法はありません-もしあれば-正しい)を持っている、それは私たちのフォーマットのために、おそらくあまりにも広いです。」(出典:ヘルプセンター
Xen2050

4
@ Xen2050同じ質問を読んでいますか?それは私に非常に固有のようです-ティーとパイプの違いは何ですか?2つの文を使用して適切に回答されています。本全体とはほど遠い。いくつかの回答が接線を離れることを選択するという事実は、質問の範囲とは関係ありません。
ジョンベントレー

@JonBentley:同じ質問を読んでいますか?R Moogのようなソートは、かなりよく焦点を絞った質問を意味します-I / Oリダイレクトtee の違いは何ですか?  「やなどのシェルパイプリダイレクト」と言っているという事実は、それが有利な点ではなく、不明確として閉じることの論拠です。しかし、実際には複数の質問があります:「目的は何ですか?」、「シェルパイプリダイレクトで同じことができることを知らない人のために発明されたのですか?」、「見えない隠れた機能は何ですか?」これらの質問のうち少なくとも2つは広すぎます。>>>teeteetee
Gマン

回答:


242

あなたが表示されないことはつまりdo_something | tee -a logfileに出力を置くlogfile しながら、stdoutにdo_something >> logfileそれを置くだけでログファイルに。

目的はtee、1つの入力、複数の出力シナリオを作成することです-「T」交差のように。

編集

どのteeようにのより多くの見かけ上の使用を可能にするかについてのコメントがありましたsudo。これはポイントの横にある:catddまたは多分より良いbufferあなたが複数の出力を必要としない場合には、優れたパフォーマンスと、この可能性を提供します。tee「できること」ではなく、設計されているものに使用する


37
複数の出力が重要です。tee複数の引数を取り、一度に多くのファイルに書き込むこともできます。
カミルマシオロウスキ

20
交差点(道路の交差点など)ではなく、T字管継手と呼びます。
user20574

7
catteeはなく、簡単な方法でどのように使用しecho /var/work/core.%p | sudo tee /proc/sys/kernel/core_patternますか?echo /var/work/core.%p | sudo cat > /proc/sys/kernel/core_patternリダイレクトは非sudoシェルによって処理されるため、機能しません。動作しますが、特に下、しばしば大きな被害を行うことが可能取り押さえツールです。に関しては、RedHatまたはUbuntuベースのディストリビューションのいずれにもデフォルトではインストールされません(またはMacOS)...ddecho /var/work/core.%p | sudo dd of=/proc/sys/kernel/core_patternddsudobuffer
Digital Trauma

3
@EugenRieck主な機能であるin:out間の1:n関係について、あなたの意見を聞きます。ただし、この状況では組み込みcat/bin/cat動作もしません。どこcatから来たのかは関係ありません- >トップレベル(非sudo)シェルによって処理されます。利点teeを超えるcatこのような状況では、それは、出力ファイルは、コマンドラインのparam(とないリダイレクト)として渡すことができることです。 dd私はまだ好むと思いますけれども、確かに現実的な選択肢であるtee。このために
デジタルトラウマ

3
@EugenRieckシェルにはどのようなものがcatありtee、ビルトインされていますか?そして、どのバージョンのsudoシェルビルトインを実行できますか?
wjandrea

118

Tee 無駄ではない

とにかくそれを知っていたのでしょうか?そうでない場合は、読んでください!または、どのように機能するかはわかっているが、なぜ存在するのかわからない場合は、最後までスキップして、Unix哲学にどのように適合するかを確認してください。

であるの目的はtee

最も単純な場合、標準入力のデータを取得し、それを標準出力と1つ(または複数)のファイルに書き込みます。1つの入力を2つの出力(および2つの方向)に分割するというで、配管のティーピースに例えられています。

最初の例を見てみましょう。

do_something | tee -a logfile

これは、出力をdo_something取得してログファイルに追加すると同時に、ユーザーに表示します。実際、上のWikipediaページにteeは2番目の例としてこれがあります。

コマンドの出力を表示して既存のファイルに追加するには:

  lint program.c | tee -a program.lint

これにより、コンピューターでlint program.cコマンドの標準出力が表示され、同時にそのコピーがprogram.lintファイルの最後に追加されます。program.lintファイルが存在しない場合、作成されます。

次の例には、別の用途があります。権限のエスカレーション

許可のエスカレーションを許可するには:

cat ~/.ssh/id_rsa.pub | ssh admin@server "sudo tee -a /root/.ssh/authorized_keys2 > /dev/null"

この例は、sudoコマンドに固有の制限をバイパスするために使用されているTシャツを示し​​ています。sudo標準出力をファイルにパイプできません。標準出力ストリームをにダンプすることにより/dev/null、コンソールのミラー出力も抑制します。上記のコマンドは、ユーザーの公開キーをサーバーのキー認証リストにインストールすることにより、現在のユーザーにssh経由でサーバーへのルートアクセスを許可します。

または、あるコマンドの出力を取得し、それをどこかに書き、それを別のコマンドへの入力として使用することもできますか?

teeコマンドを使用して、コマンドの出力をファイルに保存し、入力と同じ出力を別のコマンドにリダイレクトすることもできます。

次のコマンドは、crontabエントリのバックアップを取得し、crontabエントリをsedコマンドへの入力として渡します。sedコマンドは置換を実行します。置換後、新しいcronジョブとして追加されます。

$ crontab -l | tee crontab-backup.txt | sed 's/old/new/' | crontab –

Teeコマンドの使用例のクレジット)

Tee Unixの哲学で動作します:

1つのことを実行するプログラムを作成し、それを適切に実行します。連携して動作するプログラムを作成します。テキストストリームを処理するプログラムを作成します。これはユニバーサルインターフェースであるためです。

Unix哲学の基礎に対するクレジット)

tee これらすべてに適合:

  • それは一つのことをします:入力の余分なコピーを作成します
  • 上記の例のように他のプログラムが連携できるのは、接着剤(または、必要に応じて 'T'配管部品)であるため、他のプログラムで動作します。
  • これは、標準入力で指定されたテキストストリームを操作することによって行われます

3
@Joeは:sudo tee -aおそらく、より最近の技術革新である(私は最初ウィキ特に中のものを設定するために/ Ubuntuのガイドにそれを見た/proc/sysのUbuntuへの切り替えがあったので、私はに切り替えたときに、sudoUbuntuのがデフォルトで設定されている方法に基づくシステム()の代わりに使用しsuてルートパスワード)。teepredates だと思うsudoので、tee存在する理由ではありません。teeその必要はありませんsudo sh -c 'cat > output'。対話型で入力する方が短いのです。
ピーター

1
bashのような最新のシェルを使用teeすると、などの2つのパイプラインをフィードできますfoo | tee >(pipe2) | pipe1。またはffmpeg ... |& tee /dev/tty | sed 's/.*\r// > encode.log、ttyでステータス行の更新をインタラクティブに確認しながら、実際のログ記録のために改行ではなくキャリッジリターンで終わる「行」を削除するのも楽しい方法です。(つまり、ステータス行の更新を除外します)。一般tee /dev/ttyに、パイプラインのどこにでもデバッグプリントとして貼り付けることができます。
ピーター

2
これは、作業中のsudoの制限ではなく、シェルの>の解釈の制限です。sudoを使用してコマンドを実行すると、そのstdoutがシェルプログラムに返され、さらに>を使用したリダイレクトがシェルの権限で実行されます。昇格されたアクセス許可で書き込みたい場合、パイプラインの昇格された部分が書き込みを行うようにする必要があります。目的の効果に応じて、これを行う方法は多数あります。本当に使用したい場合は、「sudo bash -c "command> outfile"」のようなものが仕事をします。
パーキンス

まさに、@ Perkins。シェルは、解析して>も得るsudoの前にリダイレクトを設定しexec、それはですので、D」を間違いなく、それはそれは見たことがない、物事を処理していないことにsudoを制限するものではありません。:)私は通常、sudo自体を説明するのではなく、これを説明するときに「sudoワークフロー」または類似の用語と呼んでいます。
ダニーザウアー

sudo tee -a私見はティーの乱用です。使用しsudo catsudo dd(多くの場合、最高のパフォーマンスで)、またはsudo bufferあなたが複数の出力を必要としない場合。
オイゲンリーク

70

これは実質的に同じであり、入力するキーボードヒットが少なくなります。

それはまったく同じではありません...

以下は多少同等のように見えますが、そうではありません:

$ echo "hi" > test.txt
$ echo "hi" | tee test.txt
hi

重要な違いは、以下に示すように、前者は名前付きファイルにのみデータを書き込み、後者はhi端末(stdout名前付きファイルに書き込みを行うことです。

リダイレクトとティー


teeあなたがファイルにデータを書き込むことができますし、あなたが有益な事をすることができ、以降のパイプラインでそれを使用する-パイプラインの途中からデータを維持するように:

grep '^look ' interesting_file.txt \
  | tee interesting_lines.txt \
  | sort

または、パイプライン全体に昇格された特権を与えることなく、昇格された特権でファイルに書き込むことができます(ここでechoはユーザーとして実行さteeれ、ファイルへの書き込みはとして実行されますroot)。

echo 0 \
  | sudo tee /proc/sys/net/ipv4/ip_forward

を使用するとtee、多くのファイル(および stdout)に書き込むことができます。

echo "hi" \
  | tee a.txt b.txt

execwith を使用しteeて、スクリプトのすべての出力をファイルに記録しながら、オブザーバー(stdout)にデータを表示させることもできます。

exec > >( tee output.log )

2
exec > >(tee "$LOGFILE") 2>&1スクリプトがstdoutとstderrの両方、stdoutとが指すファイルを出力できるbashスクリプトでは忘れないでください$LOGFILE
rexkogitans

@rexkogitans 2>&1は、cmdバッチ構文ではありませんか?
dmb

@dmb:「stderr(= 2)をstdout(= 1)と同じ場所に送信する」ためのシェル構文
psmears

@rexkogitansそれは本当に公正な質問でした、あなたが10年間「Windoze」を使用しなかったことを本当に知りません。私は2>&1、出力を落とし、Windowsのtxtファイルにエラーを出します。
dmb

1
@dmb失礼に聞こえてすみません。それは、psmearsのコメントがすべてです。明らかに、WindowsはここでUnixスタイルを採用しました。
rexkogitans

27

これはティーです:
ここに画像の説明を入力してください

T字型の管継手。入口と2つの独立した出口があります。
つまり、1つのパイプを2つに分割します。道路の分岐点のように。

同様に、標準入力を2つの別々の出力にリダイレクトできるteeパイプ(|)です。



たとえば、と入力するとしls /ます。
次のような出力が得られます。

Applications    Network     Users       bin        dev      net      private    tmp         var
Library         System      Volumes     cores      etc      home     opt        sbin        usr

出力をテキストファイルにリダイレクトしls / > ls.txtます。シェルには出力は表示されず、結果のテキストファイルにのみ表示されます。

出力を表示し、同時にテキストファイルに渡したいですか?パイプに
を追加teeします(|)すなわち:ls / | tee ls.txt


2つを比較します。

ls /          >          ls.txt
ls /        | tee        ls.txt

4
私たちが知っているように千の言葉に値する写真のための+1
Sergiy Kolodyazhnyy

庭のホースTピースを選んだ場合、ダグマキロイの元の比phorに沿っていたでしょう。
JdeBP

@JdeBP申し訳ありませんが、それが誰なのかわかりません。彼はユーティリティの元の著者か何かですか?データの流れと物理的な電流は、しばしば油圧システムと比較されますが、おそらくそれはご存知でしょう。とにかく、私はこのスタイルを選んで、とてもシンプルにしています。私は実際にそれを親しみを持たせるためにそれをやろうとしましたが、庭の種類はより多くのY字型および/またはアクセサリーなどを取り付けるための視覚的に複雑なアタッチメントを持つ傾向があります。


18

いいえ。たまたま>and >>演算子を使用してファイルにリダイレクトできる数少ない例の1つに言及します。

しかし、Teeはもっと多くのことができます。パイプするので、他の何かにパイプできます。

良い例がウィキペディアのページにリストされています

find "4DOS" wikipedia.txt | tee 4DOS.txt | sort > 4DOSsorted.txt

基本的に、Teeにパイプすることができるため、Teeから他の何かにパイプすることができます。ログファイルを書き込むことだけが必要な場合は、はい、Teeは必要ありません。


17

tee無駄にはほど遠い。私はいつもそれを使用しており、存在していることを嬉しく思います。分割したいパイプラインがある場合、これは非常に便利なツールです。非常に簡単な例は、$dtarしたいディレクトリがあり、あなたが妄想的で(私のように)、データを確実に保持するためにストレージメディアを信頼していないため、ハッシュしたいことです。最初にディスクに書き込んでからハッシュすることもできます、ハッシュする前にアーカイブが破損すると失敗します。さらに、それを読む必要があり、数百GBのサイズのファイルを頻繁に操作する場合、必要のないファイルを再度読みたくないことがわかります。

だから私は単にこれです:

tar -c "$d" | tee >(sha256sum) >(cat > "$d"".tar") > /dev/null

タールボールを作成してTにパイプし、Tが2つのサブシェルにパイプします。サブシェルの1つはハッシュ化され、もう1つはディスクに書き込まれます。

大きなファイルに対していくつかの操作を実行したい場合にも便利です。

< file.tar.gz tee >(sha256sum) >(tar -xz) /other/storage/location/file.tar.gz > /dev/null

ファイルを1回読み取り、ハッシュして(必要な状態にあるかどうかを確認できるようにします)、抽出して、別の場所にコピーします。そのために3回読む必要はありません。


3
Nitpick:teeサブシェルを作成しません。呼び出しシェルが実行されsha5sumcatその出力をに渡されるファイル記述子に接続しますtee。また、cat;の無用な使用。入力リダイレクトを使用してtee、から直接読み取ることができますfile.tar.gz
-chepner

@chepner最初の挿入については正しいですが、2番目の挿入については完全に間違っています。私はパイプラインを順番に書くのが好きなので、右側の入力を読みやすくすることはひどいことであり、そうすることは明らかに客観的に私の方法に劣り、私の主観的な好みではありません。cat愛です cat人生です。
UTF-8

6
< file.tar.gz tee >(sha256sum) ...リダイレクトの字句順序が気になる場合は、書くこともできます。それは、単一のファイルをに送るだけの完全に別個のプロセスの必要がないという事実を変えませんtee
chepner

1
@chepnerクール、ありがとう!今日何かを学びました。:)
UTF-8

1
開始 のコストcatは比較的低いです。追加の100 GiBの書き込みと読み取りのシステムコールのコストは、提案された巨大ファイルの例では、余分なCPU時間とメモリ帯域幅を確実に浪費します。メモリ帯域幅は、そのコピーによるL3キャッシュの余分な汚染は言うまでもなく、すべてのコアにわたる共有リソースであることに注意してください。Spectre + Meltdownの軽減を有効にしたx86では、システムコールは以前よりも高価になります。そのコピーの過程で、測定可能な量の余分なCPU時間を使い果たしています。また、IMO >(cat > foo)よりも理解しやすいものではありませんfoo
ピーター

12

@bertiebの回答にあるNitpickは、この例では、sudoコマンドの固有の制限を回避するためにteeが使用されていることを示しています。sudoは標準出力をファイルにパイプできません。

固有の制限はなく、コマンドの処理方法の誤解のみがあります。

例:

sudo echo 0 > /proc/sys/net/ipv4/ip_forward

現在のシェルは、コマンドラインを解析します。出力リダイレクトを見つけて実行します。次に、コマンドを実行します。このコマンドはsudo、実行されたコマンドの引数として残りのコマンドラインを提供します。現在のシェルにルート権限がない場合、出力のリダイレクトは失敗します。

echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward

これが機能するのは、出力リダイレクトがteeコマンドに延期されているためです。この時点では、コマンドはを介して実行されたため、ルート権限を持っていますsudo

sudo bash -c "echo 0 > /proc/sys/net/ipv4/ip_forward"

これは、リダイレクトを行うシェルにルート権限があるため機能します。


2
また、あなたが必要な場合がありますsudoではなく、ファイルが出力されるため、コマンドのリダイレクトはうまく動作します:sudo foo-needs-privilege > /tmp/this-output-file-doesnt
デニスウィリアムソン

10

他の人がtee言ったように、出力をコマンドにパイプすると、その出力がファイルとstdoutの両方に書き込まれます。

tee実行に時間がかかるコマンドからの出力をキャプチャし、コマンドが使用可能になったときに出力を視覚的に検査したい場合によく使用します。そうすれば、出力を検査する前にコマンドの実行が完了するのを待つ必要はありません。

まだ言及されていないように見えますが(見逃していない限り)、teeコマンドは複数のファイルに同時に書き込むこともできます。例えば:

ls *.png | tee a.txt b.txt

*.png現在のディレクトリ内のすべてのファイルを2つの異なるファイル(a.txtおよびb.txt)に一度に書き込みます。

実際、次のteeようにして、複数の異なるファイルに一度にテキストを入力できます。

$ tee --append a.txt b.txt c.txt d.txt
These lines are appended to four different files,
and are also written to stdout.
CTRL-D

9

teeの最も一般的な使用法は、テキストをファイル(またはファイル)に送信すると同時に端末でテキストを表示することです。質問の文言は、ログファイルにのみテキストを書き込むことを想定しています。ファイル名またはディレクトリ名のリストを記述してファイルをトリガーするスクリプトがあり(他のスクリプトによって非同期に処理される)、teeを使用して同じコンテンツをstdoutに送信します。すべての標準出力はログに送信されます。だから私はそれを望む場所にテキストを持っており、これをやったことを記録したログエントリを、すべて単一の「エコー」ステートメントから持っています

teeはUnixで複数の同一ファイルを作成するための最良の方法でもあります。このように複数の空のファイルを作成するために時々使用します...

:|tee file01 file02 file03

5
どうしてtouch?(何が起きているのかがすぐにわかります)
Attie

@Attie touchは、ファイルが既に存在する場合は切り捨てず、タイムスタンプを更新してコンテンツをそのままにします。しかし、teeそれらを切り捨てます。また、やってrm+にtouch比べて異なっているtee(ハードリンクとシンボリックリンクについて考える)
マティヤNalis

では、なぜtruncate -s 0ですか?:-)
Attie

1

あなたはログファイルにコマンドの出力を書きたい、想像 stdoutに出力します。同時にそれを行う必要があるときは、が必要teeです。

ユースケースは、ビルド全体を標準出力(Jenkinsなど)に書き込むと同時に、重要なものを別のログファイル(要約メール用)に書き込むビルドスクリプトを用意することです。

teeWindowsでスクリプトを作成する必要がある場合、本当に行方不明になります。ありませんしtee、それは本当に迷惑です。


作成するのは簡単ではありませんか?
軌道での軽量レース

コマンドからの出力ストリームを簡単に分割できないため、batch / cmdでは不可能です。
ドミ

正しいが、3行のC ++プログラムのように...
オービットでの軽量レース

1
Windows unxutilsディストリビューションには多くのUnixコマンドラインツールがあり、一部のディストリビューションとは異なり、Windows実行環境を汚染しません。最大の制限は「glob」bingで、これはWindowsとUnix / Linuxで動作が異なります。「tee」は利用可能なツールの1つです。
cmm

2
ばかげてはいけません、それは2018年です。Powershellを使用してくださいtee。Cmdは、本格的なスクリプト作成を目的としたものではありませんでした-それがVBSの目的です。Powershellは、新しいスクリプトツールです。確かに、Cmdはまだかなり強力ですが、コマンドラインツールはほとんどありません。
ルアーン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.