From 560f224828763c8c3a8cf3ccc9eff5c5889963f4 Mon Sep 17 00:00:00 2001 From: Juhani Pelli Date: Mon, 5 Aug 2024 22:15:14 +0300 Subject: [PATCH] Improve run_parallel.sh --- Taskfile.yml | 8 +----- run_parallel.sh | 62 ++++++++++++++------------------------------ run_parallel_task.sh | 8 ++++++ 3 files changed, 29 insertions(+), 49 deletions(-) create mode 100755 run_parallel_task.sh diff --git a/Taskfile.yml b/Taskfile.yml index c978672..541d50a 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -46,13 +46,7 @@ tasks: vars: TASKS: '{{.TASKS | default ""}}' cmds: - - | - tasks=({{.TASKS}}) - args=() - for task in "${tasks[@]}"; do - args+=("$task" "task $task") - done - ./run_parallel.sh "${args[@]}" + - ./run_parallel_task.sh {{.TASKS}} start-gateway: desc: Start gateway services in parallel diff --git a/run_parallel.sh b/run_parallel.sh index 3d1c35b..d9a5e63 100755 --- a/run_parallel.sh +++ b/run_parallel.sh @@ -2,20 +2,15 @@ # Function to execute a command and print its output with colorized label prefix run_command() { - local command="$1" - local label="$2" - local color_code=$((31 + $(($RANDOM % 7)))) - # Use a subshell to prefix each line of output with the colorized label - ( - eval "$command" 2>&1 | while IFS= read -r line; do - # Use printf instead of echo for reliable escape sequence interpretation - printf "\e[${color_code}m[%s]\e[0m %s\n" "$label" "$line" - done - ) & + local label="$1" + local command="$2" + local color_code="$3" + eval "$command" 2>&1 | sed -u "s/^/\x1b[${color_code}m[${label}]\x1b[0m /" } +export -f run_command # Trap CTRL+C to kill all background processes -trap 'kill $(jobs -p); echo "Interrupted by CTRL+C"' INT +trap 'parallel --halt now,fail=1 kill {}' INT # Process command-line arguments if [[ $# -lt 2 ]]; then @@ -23,37 +18,20 @@ if [[ $# -lt 2 ]]; then exit 1 fi -# Use a regular array to store label-color pairs (works on both macOS and Linux) -label_colors=() - -# Loop through arguments and run commands in parallel -for i in $(seq 1 2 $#); do - if [[ $((i % 2)) -eq 1 ]]; then - label="$1" - shift - command="$1" - shift - - # Assign a color to the label if not already assigned - color_assigned=false - for j in "${!label_colors[@]}"; do - if [[ "${label_colors[$j]}" == "$label" ]]; then - color_assigned=true - break - fi - done - - if ! $color_assigned; then - color_code=$((31 + $(($RANDOM % 7)))) - label_colors+=("$label") - label_colors+=("$color_code") - fi - - run_command "$command" "$label" - fi +# Create arrays for labels, commands, and colors +labels=() +commands=() +colors=() + +# Loop through arguments and populate arrays +while [[ $# -gt 0 ]]; do + labels+=("$1") + commands+=("$2") + colors+=($((31 + RANDOM % 7))) + shift 2 done -# Wait for all background processes to finish -wait +# Use parallel to run commands +parallel --halt now,fail=1 --line-buffer --link run_command {1} {2} {3} ::: "${labels[@]}" ::: "${commands[@]}" ::: "${colors[@]}" -echo "All commands finished!" \ No newline at end of file +echo "All commands finished!" diff --git a/run_parallel_task.sh b/run_parallel_task.sh new file mode 100755 index 0000000..982b918 --- /dev/null +++ b/run_parallel_task.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +tasks=($@) +args=() +for task in "${tasks[@]}"; do + args+=("$task" "task $task") +done +./run_parallel.sh "${args[@]}"