GNU Parallel はシェルスクリプトの並列処理を簡単に実現できるツール。
一番シンプルな使い方は、標準入力でコマンドを受け取り、それを並列で実行するというもの。以下のようなオプションをよく使うのでコピペ&振り返りがしやすいようにまとめておく

cat tasks.txt | parallel --jobs 40% --bar --joblog joblog.tsv --result joblog.tsv --timeout 30m
  • tasks.txt のそれぞれの行に実行したいシェルスクリプトを記入しておく
  • --bar はプログレスバーで進捗を表示
    • --bar--eta の強化版。--eta--progress の強化版。とりあえず --bar を使っておけば問題ない
      • ただし、--bar--eta を使うと、コマンドが全部でいくつであるかを先に知る必要が出るため、すべてのコマンドを受け取り終わってからでないとコマンドの実行が始まらない。
    • parallel でコマンドを実行する際、出力はコマンド全体が終わるまで画面に書き出されないのだが、--lb を指定するとコマンドの出力を随時画面に書き出す。 --bar とは相性が悪いが、結果を常に確認したいときに使うとよい
  • --jobs で CPU 使用率を指定する代わりに -j 4 のようにすると並列処理数を直接指定できる
  • --halt now,fail=1 とすると 1 つでもジョブが失敗したらその時点で止める
  • --joblog joblog.tsv でコマンド実行履歴をファイルに保存しておける。更に以下のオプションを付けることで、この実行履歴を再実行に使うことができる
    • --resumeまだ実行していなかったタスクを再実行できる
    • --retry-failed失敗したタスク(エラーコードが非ゼロのタスク)だけをもう一度実行できる
    • --resume-failed で失敗したタスクとまだ実行していなかったタスクを両方再実行できる
  • --results parallel_log
    • コマンド・標準出力・標準エラー出力がこのディレクトリ内にそれぞれ保存される。
  • --timeout 30m
    • 30 分でジョブを強制終了する。固まったジョブが CPU・キューを占有し続けるのを防ぐのに使える。一つのジョブがあまりに長時間かかっている場合、何か問題があって詰まっている場合が多い。 parallel_log に書き出されている出力などをもとに原因を修正してから --retry-failed を行えば再実行できる