I have a bash script with a function that needs to run in parallel with different arguments. I need to know if at least one of the executions failed (returned non-zero) - doesn't matter how many failed.
The command accepts an array of parameters for the execution. I need to limit the concurrency to 4 concurrent runs due to high load. I also need to print the logs in the parent process (the one that runs the bash script)
this is the function I'm running:
function run_and_retry {
EXIT_STATUS=0
$COMMAND || EXIT_STATUS=$?
if [ $EXIT_STATUS -ne 0 ]; then
EXIT_STATUS=0
$COMMAND || EXIT_STATUS=$?
fi
return $EXIT_STATUS
}
I've tried using GNU parallel and xargs and encountered issues with both.
With xargs: (couldn't get the exit status out of it, and it also didn't work when I ran it in TravisCI)
PARAMETERS=(first-parameter second-parameter third-parameter)
export -f run_and_retry
echo "${PARAMETERS[@]}" | xargs -P 4 -n 1 -I {} bash -c "run_and_retry {}"
With GNU parallel:
PARAMETERS=(first-parameter second-parameter third-parameter)
export -f run_and_retry
parallel -j 4 -k --lb 2 run_and_retry {} ::: echo "${PARAMETERS[@]}"
How can I run multiple programs in parallel from a bash script? You have various options to run programs or commands in parallel on a Linux or Unix-like systems: => Use GNU/parallel or xargs command. => Use wait built-in command with &. => Use xargs command.
As a basic way to run commands in parallel, we can use the built-in Bash ampersand & operator to run a command asynchronously so that the shell doesn’t wait for the current command to complete before moving on to the next one: $./process 1 & $./process 2 &
We can also run multiple commands as different jobs to let them run in parallel. To achieve that, we add the “ & ” operator to the command or command group we want to send to the background, for example: In the example above, we’ll start three jobs, and they run in parallel:
3. Using & As a basic way to run commands in parallel, we can use the built-in Bash ampersand & operator to run a command asynchronously so that the shell doesn’t wait for the current command to complete before moving on to the next one: This will create two processes that will start at essentially the same instant and run in parallel.
You are so close to getting the syntax of GNU Parallel correct:
COMMAND=echo
PARAMETERS=(first-parameter second-parameter third-parameter)
parallel -j 4 -k --retries 2 "$COMMAND" {} ::: "${PARAMETERS[@]}" ||
echo $? commands failed. More than 99 if $? = 100
Or if you really insist on doing the retrying yourself:
PARAMETERS=(first-parameter second-parameter third-parameter)
export -f run_and_retry
parallel -j 4 -k run_and_retry {} ::: "${PARAMETERS[@]}" ||
echo One or more commands failed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With