Linuxコマンドを学習すると、コマンドの実行結果を次のコマンドの引数としてくれるxargsというものが出てきます。
例えば、以下のようなフォルダとファイルがあるとします。
(雑な図ですみません)
以下のコマンドを打ってみます。
$ ls test*.txt | xargs cat
>>>
log1
log2
lsコマンドで出てくる「test1.txt, test2.txt」をcat(ファイルの中身の表示)の引数としてxargsが架け橋のようにして持ってきてくれて、cat test1.txt
, cat test2.txt
を一気に反映してくれます。
ふむふむ。。
ここで自分が気になったのが、「でも、Linuxコマンドには『|』がそもそもあるけど、わざわざxargs使うのってどういうの?」って感じました。
試しに 上記のコマンドをxargs抜きで実行してみました
$ ls test*.txt | cat
>>>
test1.txt
test2.txt
ファイル名がconcatenateされて出てきました。
摩訶不思議。。
ここで、自分なりに色々調べてみると、
Linuxには「標準出力」と「引数」という区別があるということに行きつきました。
踏み込んだ話になりそうでしたが、Linux初学者(私)が色々調べてみました。
xargsは何をしているのか?
xargsは「標準入力やファイルからリストを読み込み、コマンドラインを作成して実行する」というコマンドだそうです
(引用元: https://atmarkit.itmedia.co.jp/ait/articles/1801/19/news014.html)
ls test*.txt | xargs cat
は最初に解説した通り。
|(パイプ)は何をしているのか?
パイプとは、Linuxコマンドを使って標準出力された内容を次のコマンドへ橋渡しするために使われるコマンド
だそうです(引用元: https://academy.gmocloud.com/know/20210630/12090)
つまり、「標準出力」が次のコマンドに引き渡されます。
パイプラインと親和性が高いコマンドの一つにgrepコマンドを思い浮かべる方も多いと思いますが、試しにgrepのパターンで見てみましょう
ls | grep *st1.txt
>>> test1.txt
ls | xargs grep *st1.txt
>>> (何もなし)
ls | grep *st1.txt
はlsコマンドで出力された結果
「test1.txt, test2.txt, hoge.txt」の中から、[*st1.txt]に合致するファイルを検索しているため、
最終的な出力は「test1.txt」になります。
では、ls | xargs grep *st1.txt
はlsコマンドで出力されたものを「引数」としてgrepに渡している結果、ファイル名として認識せず何も出力されずに終わった、と考えました
(この辺、自分の仮説に近い段階のため、正確な理解をしたらまた書き直します。)
終わり
一応、ここで終わるんですが、個人的に使い分けは、利用したいlinuxコマンドをちゃんと理解しなければ使い分けるタイミングは難しいと感じています。
暗記する必要はもちろんないなくて、不具合が出たらその度に調べる必要でいいのかなと思います。
今回参考にさせていただいた記事
xargsとパイプの違いについて
Linuxコマンドで使われるパイプ(|)の使い方を詳しくご紹介!
【 xargs 】コマンド――コマンドラインを作成して実行する