Infra Engineer

teeコマンドとxargsコマンド
2022.10.31
Lv1

teeコマンドとxargsコマンド

この記事を読んでほしいひと

LPIC level1習得を目ざす、初学者のかたへ。
コマンドの基本的な使い方について、解説をします。


今回の内容

今回は、teeコマンドとxargsコマンドについて解説します。
teeコマンドは標準入力と関係がある単元です。xargsコマンドは標準入力として引数のリストを与え、、findコマンドとともによく使用されます。ともに標準入力と関係がある単元なので、不安な方は標準入力について解説している記事を読んでみてくださいね。それでは解説をはじめていきましょう。

・teeコマンド
・xargsコマンド
・まとめ
・確認問題

teeコマンド

teeコマンドとは、標準入力から読み込んだ内容を、ファイルと標準出力の両方へ出力させることができます。標準出力のリダイレクトを用いると、画面からファイルへ変更することができます。このとき画面へは出力されなくなってしまいます。このteeコマンドを用いることで、ファイルへ出力すると同時に画面へも出力することができるのです。

teeコマンドの書式
 tee <ファイル名>

それでは実際にteeコマンドを使用してみましょう。まずリダイレクトにより標準出力をsak1.txtにすることで、画面上に出力されないことを確認します。つぎにteeコマンドにより標準出力をsak2.txtと画面にします。

[root@localhost Documents]# echo hoge &gt; sak1.txt  #hogeをsak1.txtに出力する
[root@localhost Documents]#
[root@localhost Documents]# cat sak1.txt
hoge
[root@localhost Documents]# echo fuga | tee sak2.txt #fugaをsak2.txtと画面に出力する
fuga
[root@localhost Documents]# cat sak2.txt
fuga

リダイレクトを使用したときは画面上に出力されずにsak1.txtに出力されましたが、teeコマンドを使用することで画面上にもsak2.txtにも出力されることがわかりました。
ここで「echo fuga | tee sak2.txt」というコマンドについて解説をします。まずechoコマンドによりfugaという文字列を出力します。その出力結果をパイプ(|)によりteeコマンドの標準入力として渡しています。teeコマンドに対してfugaと入力したイメージですね。そしてteeコマンドによりsak2.txtと画面に出力がされました。


xargsコマンド

xargsコマンドとは、標準入力から受けとった文字列を受けとり、コマンドを実行します。たとえばgrepコマンドを使用する場合、検索対象のディレクトリに膨大なファイルがあると「Argument list too long」というエラーが表示されます。このような場合にxargsコマンドを利用します。

xargsコマンドの書式
 xargs  <コマンド>

それではまずxargsコマンドの基本的な動きを確認してみましょう。「echo hoge」とechoコマンドによりhogeと出力し、パイプ(|)を使用することでhogeをxargsコマンドに渡します。そしてhogeをechoコマンドの引数として渡すことで「echo hoge」となり、echoコマンドによりhogeと出力します。

[root@localhost Documents]# echo hoge | xargs echo
hoge

これでは「echo hoge」と入力した場合と変わらなくてつまらない……そう思われた方、安心してください。次にxargsコマンドとよく組み合わせて用いられるfindコマンドの例を紹介します。現在sak1.txtにはhogeが、sak2.txtにはfugaが出力されているとします。

[root@localhost Documents]# ls
sak1.txt sak2.txt
[root@localhost Documents]# cat sak1.txt
hoge
[root@localhost Documents]# cat sak2.txt
fuga
[root@localhost Documents]# find . -name "*.txt" | xargs grep hoge
./sak1.txt:hoge

findコマンドにより、カレントディレクトリ以下からファイルの末尾が「.txt」であるファイルを検索します。その検索結果をパイプ(|)によりxargsコマンドの標準入力に渡します。xargsコマンドはその検索結果を受けとりgrepコマンドに引数として渡して、hogeという文字列が含まれているファイルを検索します。

(……ここまで読まれた方お疲れさまです。次に話す内容は少し発展的な内容を含むことになります。今までの内容ちょっと難しいなぁ…と感じられた方は確認問題に挑戦してみてください。そして次読むときにぜひ読んでみてください。もちろん初めて読む方でも分かりやすいように書いてあります。では続きをはじめましょう!)

こんどは3つのファイルがありますが、ファイル名がsak1.txtとsak2.txt、sak 3.txtとします。sakと3の間に空白が空いていることに注意してくださいね。sak1.txtとsak 3.txtにはhoge、sak2.txtにはfugaが出力されています。このときxargsコマンドを使用してみましょう。

[root@localhost Documents]# ls
sak1.txt sak2.txt sak 3.txt
[root@localhost Documents]# cat "sa1.txt" "sak2.txt" "sak 3.txt"
hoge
fuga
hoge
[root@localhost Documents]# find . -name "*.txt" | xargs grep hoge
grep: ./sak: No such file or directory
grep: 3.txt: No such file or directory
./sak1.txt:hoge

grepコマンドにエラーが表示されています。この原因はsak 3.txtとファイル名に空白が入っているからです。xargsコマンドは空白あるいは改行で区切られた文字列を読みこみます。今回のケースでは、sakと3.txtという別のファイルとしてxargsの標準入力として読み込まれました。その結果、sakや3.txtというファイルは存在しないよというエラーが表示されたのです。たとえばxargsに引き渡す方法として次のような方法があります。

[root@localhost Documents]# find . -name "*.txt" -print0 | xargs -0 grep hoge
./sak 3.txt:hoge
./sak1.txt:hoge

findコマンドにおいて-pring0オプションやxargsコマンドにおいて-0オプションを使用することで、ファイルを検索することができました。

(…というわけで以上難しい内容が終了しました! xargsコマンドは長さ制限を解消するメリットがある一方、ファイル名に空白があるとうまく機能しない場合もあります。そのようなときは上記のオプションを試してみてくださいね)


まとめ

今回は、teeコマンドとxargsコマンドについて解説しました。どちらもパイプ(|)を使うことが多く、パイプ(|)は初学者の方が苦手とする論点です。コマンドを入力すること、解説に用いた簡単な例から始めてみて、得意分野にしてもらえたらと思います。
最後に確認問題で、今回の記事の知識を復習してみましょう。


確認問題

問題

1⃣コマンドの標準出力をファイルに保存すると同時に画面上にも表示したい場合、どのコマンドを使用するか。
①tea ②tee ③t ④tail
2⃣findコマンドとよく用いられる、受けとった文字列を与えられたコマンドに渡すコマンドはどれか。
①xargs ②xeyes ③yum ③zcat

解答
答え:1⃣②、2⃣①