web-dev-qa-db-ja.com

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

私が今まで見た tee の使い方はすべて次のとおりです。

 do_something | tee -a logfile

または

do_something_else | tee logfile

teeは、シェルパイプのリダイレクトでも同じことができることを知らない人のために考案されたものですか?といった:

do_something >> logfile

または

do_something_else > logfile

それは実質的に同じであり、そしてそれはタイプアウトするのにより少ないキーボード打撃を要する。 teeに表示されない隠された機能は何ですか?

90
R Moog

見えないのは、do_something | tee -a logfileは出力をlogfileに標準出力に入れますが、do_something >> logfileはそれをに置くだけです。ログファイルにを追加します。

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

EDIT

どのようにしてteeSudoのより明白な使用を可能にするかについてのコメントがありました。これは重要なことではありません。catdd、あるいはおそらくより良いbufferは、複数の出力を必要としないのであれば、より良いパフォーマンスでこの可能性を提供します。設計上の目的でteeを使用してください。「できること」ではありません。

242
Eugen Rieck

Teeは役に立たない

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

teeの目的は何ですか

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

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

do_something | tee -a logfile

これはdo_somethingの出力を取得してログファイルに追加すると同時に、ユーザーに表示します。実際、 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コマンドの固有の制限をバイパスするために使用されるteeを示しています。 Sudoは標準出力をファイルにパイプできません。標準出力ストリームを/dev/nullにダンプすることにより、コンソールのミラー出力も抑制します。上記のコマンドは、ユーザーの公開キーをサーバーのキー認証リストにインストールすることにより、現在のユーザーにssh経由でサーバーへのルートアクセスを許可します。

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

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

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

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

Teeコマンドの使用例

Teeは、Unixの哲学で機能します。

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

(クレジット- nix哲学の基礎

teeはこれらすべてに適合します。

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

それは実質的に同じであり、そしてそれはタイプアウトするのにより少ないキーボード打撃を要する。

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

以下は多少同等ですが、そうではありません。

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

重要な違いは、前者は名前付きファイルにのみデータを書き込み、後者は名前付きファイルに端末(histdoutを書き込んだことです。下に示された:

redirect vs tee


teeを使用すると、データをファイルに書き込むことができます および それを前方のパイプラインで使用すると、パイプラインの途中からデータを保持するなどの便利なことができます。

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

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

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

teeを使うと、たくさんのファイルに書くことができます(stdout):

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

オブザーバ(exec)にデータの参照を許可しながら、スクリプトのすべての出力をファイルに記録するためにteestdoutと一緒に使用することもできます。

exec > >( tee output.log )
70
Attie

これはティーです。
enter image description here

T字管継手です。それは入口と2つの別々の出口を持っています。
言い換えれば、それは一つのパイプを二つに分割します。道のフォークのように。

同様に、teeはパイプ(|)で、標準入力を2つの別々の出力にリダイレクトすることを可能にします。



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

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

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

出力を確認し、同時にテキストファイルに渡しますか?
あなたのパイプにteeを追加してください(|)ie:ls / | tee ls.txt


両者を比較してください。

ls /          >          ls.txt
ls /        | tee        ls.txt
27
tjt263

いいえ。>および>>演算子を使用して実際にファイルにリダイレクトできるいくつかの例のうちの1つについて言及したことがあります。

しかし、ティーはもっと多くのことができます。あなたがそれにパイプするので、あなたはそれから他の何かにパイプすることができます。

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

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

基本的には、Teeにパイプ接続することができます。そのため、Teeから他のものにパイプ接続することができます。あなたがしたいのがログファイルを書くことだけであれば、はい、それならあなたは本当にTeeを必要としません。

18
LPChip

teeは無駄には程遠いです。私はいつもそれを使っていて、それが存在していてうれしいです。分割したいパイプラインがある場合、これは非常に便利なツールです。非常に単純な例は、あなたがtarしたいディレクトリ$dを持っていて、あなたがそれをハッシュしたいということです。あなたは最初にそれをディスクに書き込んでからそれをハッシュすることができますが、それがハッシュされる前にアーカイブが破損した場合は失敗します。さらに、あなたはそれを読む必要があるでしょう、そしてあなたがたくさんのサイズが数百ギガバイトであるファイルに取り組むならば、あなたはそれがそうである必要がないならばあなたは本当に再びそれらを読みたくないことを知るでしょう。

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

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

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

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

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

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

17
UTF-8

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

本質的な制限はなく、コマンドの処理方法についての誤解だけがあります。

例:

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

現在のシェルはコマンドラインを解析します。出力リダイレクトを見つけてそれを実行します。それからSudoであるコマンドを実行し、残りのコマンドラインを実行されたコマンドの引数として提供します。現在のシェルがroot権限を持っていない場合、出力のリダイレクトは失敗します。

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

これは、出力のリダイレクトがteeコマンドに据え置かれているために機能します。この時点では、コマンドはSudoを介して実行されているため、rootパーミッションを持っています。

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

リダイレクトを行っているシェルがroot権限を持っているので、これが機能します。

12
studog

他の人が言ったように、teeコマンドへの出力のパイピングはファイルと標準出力の両方にその出力を書き込みます。

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

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

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

カレントディレクトリ内のすべての*.pngファイルを同時に2つの異なるファイル(a.txtb.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
10
J-L

Teeの最も一般的な使い方は、あなたがそれをファイルに送ると同時に端末上のテキストを見ることです。あなたの質問の文言はあなたがログファイルにテキストを書くことだけを仮定しています。私はファイルを起動するためにファイル名またはディレクトリ名のリストを書くスクリプトを持っています(非同期的に他のスクリプトによって処理されるために)そして私は同じ内容を標準出力に送るためにteeを使います。すべての標準出力はログに送信されます。だから私はそれが欲しいところに私のテキストを持っていて、私はこれをしたことを記録したログエントリを持っています、すべて単一の 'echo'ステートメントから

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

:|tee file01 file02 file03
9
Wil Young

たとえば、コマンドの出力をログファイルおよびprintに出力するとします。同時にそれを実行する必要があるときは、teeが必要です。

ユースケースは、ビルド全体をstdoutに書き込むビルドスクリプト(たとえばJenkinsの場合)ですが、同時に重要なものを別のログファイル(まとめの電子メール用)に書き込む場合です。

あなたがWindowsでスクリプトを作成しなければならないとき、あなたは本当にteeを見逃し始めるでしょう。 teeはありません、そしてそれは本当に厄介です。

1
domih