created: 2021-05-07T02:32:05.000Z

xargs にシェルの関数を渡して並列処理してもらう

普通にやると xargs にはシェルの関数を渡すことはできないが、ちょっと頑張れば xargs で関数を並列で処理させることができる。 普通は xargs ではなく for ループで処理すればいいのだが「この部分の処理だけ並列処理させたい」という場合には、その処理を関数にまとめて xargs に並列化してもらうと手軽で便利だ。

シェルの関数を渡す

まずシェルで関数を定義する。

myfunc () {
  local arg1=$1
  ...
}

それを export してサブシェルでも myfunc を使えるようにする。

export -f myfunc

xargs に -cオプションを伴ったbashコマンドとして渡す。

... | xargs -I{} bash -c "myfunc {}"

bash -c で渡すコマンドはサブシェル扱いになるので export が必要。

並列で処理させる

xargs には -P オプションがあり、これを指定すると渡した行をそれぞれ並列で処理してくれるようになる。

... | xargs -P4 -I{} bash -c "myfunc {}"

マシンのCPUコア数はOSごとにそれぞれ以下のコマンドで調べられる。

Linux

$ cat /proc/cpuinfo | grep processor
processor	: 0
processor	: 1
processor	: 2
processor	: 3

macos

$ system_profiler SPHardwareDataType  | grep Cores
      Total Number of Cores: 4

bash が必要

export -f/bin/sh の機能にないので bash でスクリプトを実行する必要がある。 コンテナ環境とかで bash が入っていない場合は使えない。

参考