こんにちは。株式会社フィックスポイントのよしだです。
今回は、xargs
コマンド活用術の発展編について発表があったため、ご紹介します。
前回の内容は下リンクより閲覧できますので、基本的な部分から読みたい!という方は是非覗いてみてください!
はじめに
今回の発表では、実務にて xargs
コマンドが役立った例を紹介しています。
具体的には、弊社製品 Kompira cloud の構成ファイル生成を並列化できたため、xargs
コマンドによる有用性を共有したようです。
その際に、xargs
を使用すると手軽に処理の並列化ができるため、オススメなのだそうです😊
では早速、本題へと入りましょう!
for
文の並列化
最初に、下記のような for
文を xargs
に置き換えて並列化してみます。
for src_file in $(find $src_dir -type f); do 色々な処理 done
まず、 xargs
化 をします。
--max-args=1
で 1 引数毎 (ファイル毎) にコマンドを実行するという意味です。
find $src_dir -type f | xargs --max-args=1 <色々な処理.sh>
さらに、--max-procs
オプションを使って並列化します。
引数により並列数を指定しますが、0
は CPU スレッド数と同じだけ並列化するという意味です。
find $src_dir -type f | xargs --max-args=1 --max-procs=0 <色々な処理.sh>
このような流れで xargs
を使用した並列化ができました。
同じコマンドの並列化
次に、同じコマンドによるコマンド文の並列化を考えてみましょう。
例えば、このようなコマンド例文があったとします。
kustomize build src/namespaces -o ${DIST}/namespaces.yml kustomize build src/configs/config-maps -o ${DIST}/config-maps.yml kustomize build src/configs/secrets -o ${DIST}/secrets.yml kustomize build src/apps -o ${DIST}/apps.yml kustomize build src/jobs -o ${DIST}/jobs.yml
一見、先程と同様に xargs
を使用してぱぱっと並列化できそうではありませんか?
ただ、よく見ると引数の複数個所がそれぞれ異なっていることが分かります。
それでは、どのように xargs
を使えばよいでしょうか。
前回の復習
さて、ここで一度前回の内容をおさらいしてみましょう。
前回、xargs
コマンドを下記のようにご紹介しました。
xargs は、標準入力されたデータを行ごとコマンド引数に加えるコマンドです。
実はこの説明は、正しくはありつつもきちんと網羅した説明にはなっていません。申し訳ありません。
一体全体どういうこと?と思われた方も多いかと思いますので、詳しく説明していきます。
たしかに、大抵の場合 xargs
を使う際の標準入力は
file1 file2 file3
のような形が多いです。
これは、find
コマンドや ls
コマンドなど、多くの shell コマンドは 1 行 1 情報を出力するようにできているためです。
そのため、xargs
を使用すると、下記のように行ごとそれぞれに引数へ追加されます。
コマンド file1 file2 file3
ここまでが、前回ご紹介した内容です。
オプションによる違い
前回はご紹介していないオプションを使用することによって、少し異なる処理をすることが可能となります。
先程「網羅できていない」と言ったのはこの部分を指しています。
今回注目するオプションは、-n
(--max-args
) と -L
(--max-lines
) です。
一度、先程の例について --max-args=1
と --max-lines=1
を使用してみます。
すると、
コマンド file1 コマンド file2 コマンド file3
というように、どちらも1行ごとに別々のプログラムが起動されます。
ところが、下記のように1行に複数の引数が指定されていた場合は、異なったパターンによって実行されます。
file1 file2 file3 file4
--max-args=1 の場合
コマンド file1 コマンド file2 コマンド file3 コマンド file4
--max-lines=1 の場合
コマンド file1 file2 コマンド file3 file4
--max-args
では引数ごと、--max-lines
では一行ごとに処理が行われています。
もうお気づきの方もいらっしゃるとは思いますが、先程のコマンド例文を思い出してみましょう。
kustomize build src/namespaces -o ${DIST}/namespaces.yml kustomize build src/configs/config-maps -o ${DIST}/config-maps.yml kustomize build src/configs/secrets -o ${DIST}/secrets.yml kustomize build src/apps -o ${DIST}/apps.yml kustomize build src/jobs -o ${DIST}/jobs.yml
引数の複数個所がそれぞれ異なっているため、対応に困っていましたね。
そこで、ここでは --max-lines=1
を使うことにより、xargs
化できるようになる訳です!
xargs --max-lines=1 kustomize <<EOF build src/namespaces -o ${DIST}/namespaces.yml build src/configs/config-maps -o ${DIST}/config-maps.yml build src/configs/secrets -o ${DIST}/secrets.yml build src/apps -o ${DIST}/apps.yml build src/jobs -o ${DIST}/jobs.yml EOF
※ <<EOF
の部分は、「ヒアドキュメント」で検索すると詳細が分かるかと思います。
IT用語辞典のリンクは下記の通りです。
そして最初のように並列化します。
xargs --max-lines=1 --max-procs=0 kustomize <<EOF build src/namespaces -o ${DIST}/namespaces.yml build src/configs/config-maps -o ${DIST}/config-maps.yml build src/configs/secrets -o ${DIST}/secrets.yml build src/apps -o ${DIST}/apps.yml build src/jobs -o ${DIST}/jobs.yml EOF
以上が、xargs
のオプションを使用した並列化の方法です。
ちなみに今回は、--max-args
や --max-lines
, --max-procs
等の long options 形式を使用していますが、BSD 版 xargs にはこれらのオプションがなかったり名前が違うことがあります。
以下の対応する short option を使用した方が様々な環境で動かすことができます。
long option | short option |
---|---|
--max-args |
-n |
--max-lines |
-L |
--max-procs |
-P |
参加者の反応
今回の発表を聞いた参加者の反応です。
オプションを知らなかったため勉強になった方もいたようですね😊
また一番下にあるように、質問を Slack から投げかけたりすることも可能です!
基本的には毎発表ごとに質疑応答の時間もありますので、そこでみなさん自由に質問しています♪
最後に
今回は、xargs
発展編として、手軽にシェルスクリプトで並列処理する方法をご紹介しました。
--max-lines
を活用すれば、複数引数にも対応できるため、色々な場面で並列化が可能になります!
ぜひ、xargs
を生かした並列化を試してみてくださいね。
株式会社フィックスポイントでは、一緒に働いてくれるメンバーを募集しています!
詳細は、こちらをご覧ください。