Mehrere Bash-Funktionen im Hintergrund ausführen und warten, bis sie zurückkehren

14

Dies ist ein einfaches Skript, das den nvidia-smiBefehl auf mehreren Hosts ausführt und seine Ausgabe in einer gemeinsamen Datei speichert. Das Ziel hier ist, es asynchron laufen zu lassen .

Reicht &der process_host()Funktionsaufruf am Ende aus? Ist mein Skript korrekt?

#!/bin/bash

HOSTS=(host1 host2 host3)
OUTPUT_FILE=nvidia_smi.txt

rm $OUTPUT_FILE

process_host() {
    host=$1
    echo "Processing" $host
    output=`ssh ${host} nvidia-smi`
    echo ${host} >> $OUTPUT_FILE
    echo "$output" >> $OUTPUT_FILE
}

for host in ${HOSTS[@]}; do
    process_host ${host} &
done;

wait
cat $OUTPUT_FILE
syntagma
quelle

Antworten:

13

Ja, aber Ihre Ausgabe ist möglicherweise verstümmelt. Es ist besser, wenn die Funktion ihre Ausgabe in Abhängigkeit vom Hostnamen in eine bestimmte Datei schreibt und das Ergebnis dann vom Hauptskript verkettet (und bereinigt).

Außerdem sollten Sie Ihre Variablen in doppelte Anführungszeichen setzen. Kopieren Sie das Skript und fügen Sie es in ShellCheck ein .

Vielleicht so etwas:

#!/bin/bash

hosts=( host1 host2 host3 )
outfile="nvidia_smi.txt"

rm -f "$outfile"

function process_host {
    local host="$1"
    local hostout="$host.out"
    printf "Processing host '%s'\n" "$host"
    echo "$host" >"$hostout"
    ssh "$host" nvidia-smi >>"$hostout"
}

for host in "${hosts[@]}"; do
    process_host "$host" &
done

wait

for host in "${hosts[@]}"; do
    hostout="$host.out"
    cat "$hostout"
    rm -f "$hostout"
done >"$outfile"

cat "$outfile"

Die letzte Schleife kann durch ersetzt werden

cat "${hosts[@]/%/.out}" >"$outfile"
rm -f "${hosts[@]/%/.out}"
Kusalananda
quelle
Ich bekomme genau die Ausgabe, die ich bekommen möchte, was könnte hier schief gehen?
Syntagma
2
@ ΔλЛ Wenn zum Beispiel der erste Host langsam antwortet, Processing host1folgt Processing host2und die Ausgabe von host2und nicht die Ausgabe von host1.
Kusalananda