Bashだけで並列実行を制限するコマンドキューを作る

Concurrent Shell Command Queues

Bashだけで並列実行を制限するコマンドキューを作る

Bashで並列処理を高速化しつつ同時実行数を制限したい——そのためにFIFOとxargs -Pを組み合わせ、コマンドを後から投入できるキューを自作した。queue_start、queue_submit、queue_waitの3関数で構成され、BashとZshの両方で動作する。ただし出力のストリーミング不可や終了処理の乱暴さなど既知の制約も多く、筆者自身もPythonなど別言語の利用を勧めている。

Bashが好きで、挑戦してみたかったからです。それでも、Pythonなど別の言語を使ったほうがよいでしょう。
  1. js2

    > シェルコマンドを並列実行しつつ、同時実行数を制限する方法。

    タスクによっては、Makefileを生成して次のように実行します:

    make -j <同時実行数>

    > 私の元々のユースケースは、大量のWebリクエストを行うことでした

    これはまさに、おそらく20年前に私が並列実行のためにMakefileを使うことを考えたきっかけとなったユースケースです。各URLをファイルにダウンロードするルールを作ります。そして、好きな同時実行数でシンプルに `make -j <ジョブ数>` を実行するだけです。おまけに、既にダウンロード済みのファイルは自動的にスキップされます。例えば:

    BASE := https://example.com/files

    FILES := a.txt b.txt c.txt d.txt e.txt

    .DELETE_ON_ERROR:

    all: $(FILES)

    $(FILES):

    curl -sS --fail --max-time 30 -o $@ $(BASE)/$@

    あるいは、ブログ記事の例の一つを模倣するなら:

    SHELL := bash

    .SHELLFLAGS := -o pipefail -c

    N := 1 2 3 4 5

    REQS := $(N:%=req-%)

    .PHONY: all $(REQS)

    all: $(REQS)

    $(REQS): req-%:

    @curl -sS --fail-with-body --max-time 10 -X POST -H 'Content-Type: application/json' \

    -d '{"request": $*}' https://postman-echo.com/post | jq -c .json

    実行方法:

    $ make -O -j 3

    > 実行したいコマンドをすべて事前に知っている必要はなく、時間をかけてコマンドを投入できます。

    ああ、そうですね。それはMakeを `xargs -P` / GNU `parallel` と同じカテゴリに入れることになり、もっと巧妙なものが必要になります。

  2. reconquestio

    GNU Parallelのsemもあります:https://www.gnu.org/software/parallel/sem.html

    sem --id jobs -j 2 'sleep 1; echo FIRST'

    sem --id jobs -j 2 'echo SECOND'

    sem --id jobs -j 2 'echo THIRD'

    sem --id jobs --wait

    SECOND

    THIRD

    FIRST

  3. 0cf8612b2e1e

    これにはpueueが本当に気に入っています。軽量なslurmやparallelのようなもので、引用通知に悩まされることもありません。

    https://github.com/Nukesor/pueue

この日のほかの記事

2026-11-13