マニュアルには、ティーは「パイプ フィッティング」ツールであると記載されています。ケース[1]は私を混乱させます:
1.ケース
echo "foo bar" | sudo tee -a /path/to/some/file
2.ケース
:w !sudo tee %
ケースからティーのロジックを理解するのは難しいです。ティーはどのように機能しますか?
tee
コマンド パイプラインを分割するために使用され、コマンドの出力をファイルに保存し、パイプラインに沿って送信できます。あなたが与えた最初の例では::
echo "foo bar" | sudo tee -a /path/to/some/file
「foo bar」は標準出力にエコーされ、に追加され/path/to/some/file
ます。ティーはパイプの "T" ジョイントのようなもので、出力を他の 2 つのパイプに分割します。
tee
通常、プログラムの出力を分割して、表示とファイルへの保存の両方ができるようにするために使用されます。このコマンドを使用して、データが別のコマンドまたはプログラムによって変更される前に、中間出力をキャプチャできます。tee コマンドは、標準入力を読み取り、その内容を標準出力に書き込みます。結果を指定されたファイルまたは変数に同時にコピーします
tee [OPTION]... [FILE]...
例えば
tee [ -a ] [ -i ]... [ File ]...
-a
出力を上書きするのではなく、File の末尾に追加します。
-i
割り込みを無視します。
sudo
質問の例をファイルに追加して追加する
ls -l | sudo tee -a file.txt
tee
(のように) にコピーstdin
し、さらに指定されたファイルにすべてを書き込みます。このように使用すると、情報を特権モードにプッシュし、同時に、正しいものがそこに移動したかどうかを監視できます。stdout
cat
sudo
また、シェルでリダイレクトが処理される方法により、ほぼ同等であることに注意してください。
sudo echo "foo bar" > /path/to/some/file
sudo
リダイレクトはターゲット ユーザーではなく、呼び出し元のユーザーによって行われるため、機能しません。
事例の説明
1. sudo- および -tee コマンドによる権限のエスカレーション
この例は単なるロジックではなく、慣例です。権限をエスカレートするための規則を示しています。
echo "Body of file..." | sudo tee root_owned_file > /dev/null
この例では、tee を使用して sudo コマンド固有の制限を回避しています。sudo は、標準出力をファイルにパイプできません。その stdout ストリームを /dev/null にダンプすることにより、コンソールでミラーリングされた出力も抑制します。
2. Vim で sudo コマンドを実行する
Vim では Sudo コマンドが使えるので、sudo で実行するのを忘れていた場合でも、コマンドを使用できます。/etc/init.d/ などの読み取り専用ファイルがある場所で役立ちます。
tee コマンドを使用したロジック
これは Git のブランチのようなものですが、Rick Copeland による T のアナロジーを参照してください。うまくいけば、変更された例(オリジナル)がその使用法を理解するのに役立ちます:
curl "http://en.wikipedia.org/wiki/Pipeline_(Unix)" | tee original_site | sed 's/[^a-zA-Z ]/ /g' | tr 'A-Z ' 'a-z\n' | grep '[a-z]' | sort -u | comm -23 - /usr/share/dict/words
のターゲットはtee
通常のファイルに限定されず、デバイス、FIFO などにできることに注意してください。また、別のtee
呼び出しなどにパイプすることもできます。:-)
tee
このコマンドは、長いパイプラインを含むシェルスクリプトのデバッグに非常に役立つことがわかりました。これは、Perlでの書き換えが10年遅れている、恐ろしいシェルスクリプトの最後尾ですが、それでも機能します。(最後に変更されたのは1998年です。)
# If $DEBUG is yes, record the intermediate results.
if [ "$DEBUG" = yes ]
then
cp $tmp.1 tmp.1
cp $tmp.2 tmp.2
cp $tmp.3 tmp.3
tee4="| tee tmp.4"
tee5="| tee tmp.5"
tee6="| tee tmp.6"
tee7="| tee tmp.7"
fi
# The evals are there in case $DEBUG was yes.
# The hieroglyphs on the shell line pass on any control arguments
# (like -x) to the sub-shell if they are set for the parent shell.
for file in $*
do
eval sed -f $tmp.1 $file $tee4 |
eval sed -f $tmp.3 $tee5 |
eval sh ${-+"-$-"} $tee6 |
eval sed -f $tmp.2 $tee7 |
sed -e '1s/^[ ]*$/--@/' -e '/^--@/d'
done
実行される3つのsedスクリプトは恐ろしいものです-私はそれらを表示する予定はありません。これは、の半ばまともな使用法でもありeval
ます。通常の一時ファイル名($ tmp.1など)は固定名(tmp.1など)で保持され、中間結果はtmp.4..tmp.7に保持されます。コマンドを更新する場合、図のよう"$@#"
に''の代わりに' $*
'を使用します。そして、私がそれをデバッグしているとき、引数リストにはファイルが1つしかないので、デバッグファイルの踏みつけは私にとって問題ではありません。
必要に応じて、一度に入力の複数のコピーを作成できることに注意してください。tee
あるコマンドを別のコマンドにフィードする必要はありません。
誰かがそれを必要とする場合、私は、複数のファイルではなく、複数のパイプラインに出力のコピーを送信するtee
calledのバリアントを持っています。tpipe
パイプライン(または標準出力)の1つが早期に終了しても、それは継続します。(連絡先情報については、私のプロファイルを参照してください。)
teeは、単に出力をファイルにミラーリングします。このファイルは、 teeの引数として指定できます。
teeがスーパーユーザーとして( sudoを介して)呼び出されていることを示す場合、その唯一の目的は、エコーを実行するユーザーではなくスーパーユーザーとしてファイルを書き込むことです。