rm /blog

IT系技術職のおっさんがIT技術とかライブとか日常とか雑多に語るブログです。* 本ブログに書かれている内容は個人の意見・感想であり、特定の組織に属するものではありません。/All opinions are my own.*

【UNIX】xargsコマンド自分用解説

UNIXコマンドxargsの簡単な使い方メモ。
例によって自分用の備忘録を兼ねる。

xargsはコマンドを呼ぶためのコマンドという感じだ。
xargsの引数に「実行したいコマンド」そのものをひきわたす。
通常標準入力から「実行したいコマンド」に渡す引数を入力するが、
スクリプトに組み込まれているようなケースではパイプと連動して使うことが多いはずだ。

 
非常に単純な例でいうと以下のような使い方ができる。

echo test.txt | xargs ls

この例はカレントディレクトリにある「test.txt」をコマンドlsに渡せ、
という指示を意味している。つまり早い話が

ls test.txt

と同じ。この程度ならこう書いたほうが絶対早いしわかりやすい。

当然他の使い方もあるが、個人的によく使うのがfindを絡めたやり方である。
例えば

find ./* -ls | awk '{print $11}' | xargs ls -las
①             ②                  ③

といったものである。
この例では
①カレントディレクトリ配下をfindしてきて、
②「ファイル名」または「ディレクトリ名」にあたる部分だけを取り出し、
③それをxargs経由で「ls -las」に引き渡して実行させる
ということを実現している。

これは端的に言えば「カレントディレクトリ配下の全ファイル・ディレクトリをlsする」だけなので、
xargsを使わなくても以下のようなスクリプトで同じことを実現は可能である。

for i in `find ./* -ls | awk '{print $11}'`; do
	ls -las $i
done

個人的にはこっちの方がわかりやすいのだが、行数が3行になる(※)し
コマンドライン上で実行できない(shファイルとかに記述する必要が出てくる)こともあり、
1行で書ける=コマンドライン上で実行できるxargsの方がスクリプトの見た目はきれいになる。

(※)forは;(セミコロン)区切りでスクリプト上の改行を表現できるから下記のように無理矢理書けば1行で書けるしコマンドライン上でも実行可能になる

for i in `find ./* -ls | awk '{print $11}'`; do ls -las $i; done



ここでは簡単のためxargsの実行コマンドをlsにしているが、別にコマンドは何でもよい。
例えば下記の例はカレントディレクトリ配下の(サブディレクトリ配下を含めた)全ファイルをgzipで圧縮する。

find ./* -type f -ls | awk '{print $11}' | xargs gzip

サーバ内のディスク容量圧迫を避けるため、
定期的(1日1回とか)に圧縮をかけて容量削減を図る目的等に使用できる。

ちなみにxargsは変な戻り値をもっている。

戻り値 意味
0 成功
123 実行のいずれかにおいて、 1-125 の戻り値が返った。
124 command が 255 を戻り値として返した。
125 command がシグナルによって kill された。
126 command が実行できない。
127 command が見つからない。
1 他のエラーが起こった。

これはxargsが他のコマンドを実行するための経由点であり、
実際に実行することになるコマンドがxargsそれ自体からは想定しきれないためだろう。
0が成功なのは他と変わりないから0かそれ以外で見れば事足りるような気はする。