▲ 26 r/bash

What’s a robust Bash pattern for running N concurrent jobs with proper cleanup and exit code aggregation?

I’m trying to build a Bash script that processes a list of tasks in parallel with a fixed concurrency limit (e.g., 4 jobs at a time), but I also want it to behave robustly in real-world conditions.

Specifically, I want to:

Limit the number of concurrent background jobs using pure Bash (no GNU parallel).

Correctly capture and aggregate exit codes from all jobs.

Handle SIGINT/SIGTERM so that if the script is interrupted, it cleanly terminates all running child processes.

Avoid leaving orphaned or zombie processes.

I’ve experimented with wait -n, job control, and traps, but I’m running into edge cases where some processes don’t terminate properly or exit codes get lost.

What’s a solid pattern or structure in Bash to implement this kind of controlled parallel execution with proper signal handling and cleanup?

reddit.com
u/fdelux6 — 1 month ago
▲ 8 r/Fedora+1 crossposts

Hey r/fedora! 👋

A few months ago I shared a fish shell function to browse RPM installation history. It got a good reception and has evolved quite a bit since, so here's an updated post — and this time there's a bash version too for non-fish users.

What problem does it solve:

dnf history is powerful but noisy when you just want to know what was installed and when. I use this tool to get a quick, clean picture of recent system changes.

Practical example: my printer recently stopped working. rpm_installed yd showed me everything installed the day before — cups was in the list. That was enough to point me at the culprit without digging through logs.

On Fedora where updates are frequent and often come in batches, having a readable install timeline is genuinely useful.

Usage:

rpm_installed today
rpm_installed yesterday
rpm_installed days 7
rpm_installed since 2026-03-01
rpm_installed since 2026-03-01 until 2026-03-31
rpm_installed count per-day
rpm_installed count per-week

Short aliases: td, yd, lw, tm, lm

Output is grouped by date with per-day package counts, auto-pages on long output, and caches results for fast repeated calls.

Install (fish version) via Fisher:

fish

fisher install fdel-ux64/fish-rpm-installed

https://github.com/fdel-ux64/fish-rpm-installed

Install (bash version):

bash

curl -sL https://raw.githubusercontent.com/fdel-ux64/bash-rpm-installed/main/bin/rpm-installed \
  -o ~/.local/bin/rpm-installed
chmod +x ~/.local/bin/rpm-installed

https://github.com/fdel-ux64/bash-rpm-installed

Both versions tested on Fedora 43, Fedora 44 and OpenSUSE Tumbleweed.

Bonus — kver: if you're also curious where your running kernel stands relative to upstream, there's a companion fish function in my fish-config repo:

kver          # show current running kernel
kver -c       # fetch latest stable from kernel.org and compare
              # times out after 5s if kernel.org is unreachable
              # offers to open kernel.org in your default browser

https://github.com/fdel-ux64/fish-config

u/fdelux6 — 2 months ago