I have multiple "sets" of arguments for one command that I need to run in sequence (well, in parallel, technically). I also need to repeat the same logic after running each command.
#!/bin/bash
local pids=()
# Run commands in parallel.
my_command "$URL_ONE" "$URL_ONE_TEXT" "${TMP_DIR}/some_dir" &
pids+=("$!")
my_command "$URL_ONE" "$URL_TWO_TEXT" "${TMP_DIR}/some_similar_dir" &
pids+=("$!")
my_command "$URL_TWO" "$URL_TWO_TEXT" "${TMP_DIR}/third_dir" &
pids+=("$!")
my_command "$URL_THREE" "$URL_THREE_TEXT" "${TMP_DIR}/fourth_dir" &
pids+=("$!")
# ...
# Wait for parallel commands to complete and exit if any fail.
for pid in "${pids[@]}"; do
wait "$pid"
if [[ $? -ne 0 ]]; then
errecho "Failed."
exit 1
fi
done
Rather than repeating pids+=("$!")
and other portions so frequently, what I'd like to do is define an array/set of arguments, loop through it, and execute the same logic for each set of arguments. For example:
#!/bin/bash
# This wouldn't actually work...
ARG_SETS=(
("$URL_ONE" "$URL_ONE_TEXT" "${TMP_DIR}/some_dir")
("$URL_ONE" "$URL_TWO_TEXT" "${TMP_DIR}/some_similar_dir")
("$URL_TWO" "$URL_TWO_TEXT" "${TMP_DIR}/third_dir")
("$URL_THREE" "$URL_THREE_TEXT" "${TMP_DIR}/fourth_dir")
)
for arg1 arg2 arg3 in "$ARG_SETS[@]"; do
my_command "$arg1" "$arg2" "$arg3" &
pids+=("$!")
done
But Bash does not support multidimensional arrays. Does anyone have any ideas for a good pattern to make this cleaner, or do something similar in design to my second example? Thanks!
Best Answer
This approach uses three arrays, one for each argument of the
my_command
:Alternate style
Depending on how many commands are to be run, you may want to consider the following alternative for defining the arrays: