#!/bin/bash # # Run commands in parallel from a bash script, e.g. # # source "${path_to}/libparallel.sh" # for user in $( cat $user_file ); do parallel 5 # user_migrate $user & # done # # runs 5 user_migrate processes at a time, when one completes, # a new one is started # # # FOR MORE COMPLEX THINGS, SCROLL DOWN # parallel_debug() { [[ "${VERBOSE}" != "" ]] && echo "$@"; } parallel_jobs() { local i=0 while read job; do (( i++ )) done <<< "$( jobs )" echo $i } parallel_exit() { wait [[ "${PARALLEL_JOBS}" != "" ]] && { echo "parallelized ${PARALLEL_JOBS} jobs with ${PARALLEL_SLEEPS} sleeps" } PARALLEL_JOBS="" PARALLEL_SLEEPS="" } parallel_sleep() { while [[ $( parallel_jobs ) -ge $max ]] ; do (( PARALLEL_SLEEPS++ )) parallel_debug " sleeping until queue not full" sleep 1 done } parallel() { local max=10 [[ "${1}" =~ ^[0-9]+$ ]] && { max=$1 } [[ "${PARALLEL_EXIT_HANDLER_IS_DISABLED}" == "" ]] && { trap parallel_exit EXIT } parallel_debug $( printf "queue depth %3d/%d\n" $( parallel_jobs) $max ) parallel_sleep } # # To maintain serialization, use a subshell, e.g. # # for user in $( cat $user_file ); do parallel 5 # ( user_migrate $user # fw_update $user ) & # done # # To get more reporting per job, use parallel_exec, e.g. # # for user in $( cat $user_file ); do # N=5 parallel_exec user_migrate $user # done # # Default parallelism = 10, change with N # # To get progress reporting, set VERBOSE=yes, e.g. # # VERBOSE=yes # for user in $( cat $user_file ); do parallel 5 # user_migrate $user & # done # # If you trap EXIT already, set # PARALLEL_EXIT_HANDLER_IS_DISABLED=yes # # and call parallel_exit when your loop is done # see parallel_test() below # parallel_exec() { local max=10 [[ "${N}" =~ ^[0-9]+$ ]] && { max=$N } [[ "$PARALLEL_JOBS" == "" ]] && { PARALLEL_JOBS=0 PARALLEL_SLEEPS=0 trap parallel_exit EXIT } ( "$@" ) & parallel_debug $( printf "queue depth %3d/%d, running %s\n" $( parallel_jobs) $max "$*" ) (( PARALLEL_JOBS++ )) parallel_sleep } parallel_test() { for user in $( cat /etc/passwd ); do parallel 10 echo $user >/dev/null sleep 5 & done parallel_exit for user in $( cat /etc/passwd ); do echo $user >/dev/null N=5 parallel_exec sleep 1 done }