对于一个命令,我有多个“组”参数,我需要按顺序运行(好吧,从技术上讲,是并行的)。运行每个命令后我还需要重复相同的逻辑。
#!/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
我不想如此频繁地重复pids+=("$!")
其他部分,而是定义一个数组/参数集,循环遍历它,并为每组参数执行相同的逻辑。例如:
#!/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
但 Bash 不支持多维数组。有没有人有任何想法可以找到一个好的模式来使这个更干净,或者做一些与我的第二个例子类似的设计?谢谢!
答案1
此方法使用三个数组,每个数组对应 的每个参数my_command
:
pids=()
a=("$URL_ONE" "$URL_ONE" "$URL_TWO" "$URL_THREE")
b=("$URL_ONE_TEXT" "$URL_TWO_TEXT" "$URL_TWO_TEXT" "$URL_THREE_TEXT")
c=("${TMP_DIR}/some_dir" "${TMP_DIR}/some_similar_dir" "${TMP_DIR}/third_dir" "${TMP_DIR}/fourth_dir")
for i in ${!a[@]}
do
my_command "${a[$i]}" "${b[$i]}" "${c[$i]}" &
pids+=("$!")
done
# Wait for parallel commands to complete and exit if any fail.
for pid in "${pids[@]}"
do
if ! wait "$pid"
then
errecho "Failed."
exit 1
fi
done
另类风格
根据要运行的命令数量,您可能需要考虑以下替代方法来定义数组:
a=(); b=(); c=()
a+=("$URL_ONE"); b+=("$URL_ONE_TEXT"); c+=("${TMP_DIR}/some_dir")
a+=("$URL_ONE"); b+=("$URL_TWO_TEXT"); c+=("${TMP_DIR}/some_similar_dir")
a+=("$URL_TWO"); b+=("$URL_TWO_TEXT"); c+=("${TMP_DIR}/third_dir")
a+=("$URL_THREE"); b+=("$URL_THREE_TEXT"); c+=("${TMP_DIR}/fourth_dir")
答案2
我真的不认为需要数组,并且会选择简单的东西,例如:
f(){
my_command "$@" &
pids+=("$!")
}
f "$URL_ONE" "$URL_ONE_TEXT" "${TMP_DIR}/some_dir"
f "$URL_ONE" "$URL_TWO_TEXT" "${TMP_DIR}/some_similar_dir"
f "$URL_TWO" "$URL_TWO_TEXT" "${TMP_DIR}/third_dir"
f "$URL_THREE" "$URL_THREE_TEXT" "${TMP_DIR}/fourth_dir"