How can I run directory updates in parallel with a limit on concurrent jobs?

0
0
Asked By MellowPine47 On

I have a Bash script that finds directories matching a condition, enters each one, and runs an update command. The script works, but there are several thousand directories and each update takes a little while, so processing them sequentially is too slow. What is a good way to run the updates concurrently while limiting the number of active jobs, or alternatively divide the directories into batches and process those batches in parallel?

4 Answers

Answered By CedarBlink22 On

`xargs` can do this without requiring another parallel-processing utility. Have `update-this-dir.sh` accept a directory path and change into that directory itself, then run: `find . -type d -iname '.config' -exec dirname {} ; -print0 | xargs -0 -n 1 -P 10 -t update-this-dir.sh`. Here, `-n 1` gives each invocation one directory and `-P 10` allows up to ten concurrent processes. Using null-separated paths is safer than newline-separated output when directory names contain spaces or unusual characters.

SilverMaple31 -

If the directory list is already stored in a file with one path per line, the equivalent is `< list_of_dirs xargs -n 1 -P 10 -t update-this-dir.sh`. The input redirection goes before `xargs`; using `>` there would write output instead of supplying input.

Answered By OliveComet54 On

Tools such as `fd` can also execute matching commands concurrently, but the important design change is to pass the directory explicitly instead of relying on the caller's current working directory. That makes parallel execution safer and avoids different jobs interfering with one another. Also verify that the update operation is safe when several directories are processed at the same time, and choose the concurrency level based on disk, network, or service capacity rather than simply using the largest possible number.

Answered By QuartzRiver8 On

GNU Parallel is designed for exactly this. Generate the directory list with null separators and pass it to a worker script or command with a fixed job count. For example, make the update script accept the directory as an argument, then use something like `find . -type d -iname '.config' -exec dirname {} ; -print0 | parallel -0 -j 10 update-this-dir.sh`. The `-j 10` option keeps at most ten updates running at once.

Answered By HarborNook6 On

You can also implement a simple worker limit directly in Bash. Start each directory update in a subshell, keep its process ID, and wait whenever the number of active jobs reaches the limit. The basic pattern is: `(cd "$dir" && printf 'nn%sn' "$(realpath .)" && update-this-dir.sh --file ./name.txt) &`, followed by storing `$!` in a PID array and waiting for older entries before launching more. After all directories have been submitted, run `wait` for the remaining PIDs. Keep each job's output in a separate log if mixed terminal output would be confusing.

Related Questions

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.