So begrenzen Sie parallele Jobs

So begrenzen Sie parallele Jobs

Ich habe eine Hosts-Datei, /tmp/hostlistdie beispielsweise einen Benutzernamen und ein Kennwort zum Anmelden erfordert, und ich verwende den Befehl „expect“, um mich bei den Hosts anzumelden und den Befehl auszuführen. Das Ergebnis ist wie unten in meinem Bash-Skript dargestellt.

)

VAR=$(expect -c "$script")

echo "$VAR" >/tmp/outexp
-----------------

Ich bin in der Lage, parallele Ausführung zu handhaben -

while IFS= read -r i
do
        ( export server_name=`echo $i`;echo "connecting to $i";expect -c 
wait

Gibt es eine Möglichkeit, die Anzahl der gleichzeitig verfügbaren Hosts zu begrenzen? Nehmen wir beispielsweise an, ich habe 1.000 Hosts in einer Datei und ich möchte jeweils 100 Hosts gleichzeitig ausführen, um 1.000 Hosts abzuschließen.

Antwort1

Mit GNU Parallel würden Sie etwa Folgendes tun:

[compute $script]
export script
run_one() {
  i="$1"
  export server_name=`echo $i`
  echo "connecting to $i"
  expect -c "$script"
  echo "Job completed on $i"
  echo "-----------------------------------"
}
export -f run_one

cat "$file" | parallel -j100 run_one '2>&1' >"$log2"

Oder:

[compute $script]
export script

cat "$file" |
  parallel -j100 --tag 'i={} expect -c "$script" 2>&1' >"$log2"

Antwort2

Sie können überprüfen, wie viele Jobs ausgeführt werden, und warten, bis sie abgeschlossen sind.

Hier ist ein Beispielskript:

#!/bin/bash

i=0
while [[ $i -lt 50 ]]; do

    n=$(jobs | grep Running | wc -l)
    if [[ $n -ge 10 ]]; then
        echo "waiting for jobs to finish ($n running)"
        sleep 1
    else
        echo start next $i
        bash -c "sleep $(( $RANDOM % 3 )); echo $i finished" &
        let i+=1
    fi
done
wait

Um die Anzahl paralleler Hosts auf 100 zu begrenzen, verwenden Sie es folgendermaßen:

while IFS= read -r i
do
    n=$(jobs | grep Running | wc -l)
    if [[ $n -ge 100 ]]; then
        echo "waiting for jobs to finish ($n running)"
        sleep 1
    else
        ( export server_name=`echo $i`;echo "connecting to $i";expect -c "$script";echo "Job completed on $i";echo "-----------------------------------" ) >> "${log}_${i}" 2>&1 &
    fi
done < "$file"

Antwort3

Normalerweise verwende ich einen etwas anderen Ansatz, bei dem Sie nicht die Anzahl der von Ihnen erzeugten Unterprozesse im Auge behalten müssen. Immer wenn die Warteschlange kleiner als Ihr Maximum ist, füllt sie sich.

max_jobs=100 # set queue size
while IFS= read -r i; do
  num_jobs=$(pgrep -c -P$$)
  if [[ $num_jobs -ge $max_jobs ]]; then
    wait -n $(pgrep -P$$) # Wait until a any subprocess terminates
  else
    <calling_awesome_script_here> &
  fi
done < "$file"

verwandte Informationen