Ejecutar múltiples funciones bash en segundo plano y esperar hasta que regresen

14

Este es un script simple que ejecuta nvidia-smicomandos en varios hosts y guarda su salida en un archivo común. El objetivo aquí es hacer que se ejecute de forma asincrónica .

¿ &Al final de la process_host()llamada de función es suficiente? ¿Es correcto mi guión?

#!/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
sintagma
fuente

Respuestas:

13

Sí, pero su salida puede estar confusa. Es mejor que la función escriba su salida en un archivo específico dependiendo del nombre del host y luego deje que el script principal concatene el resultado (y lo limpie).

Además, debe comillas dobles sus variables. Copie y pegue el script en ShellCheck .

Tal vez algo como esto:

#!/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"

El último bucle puede ser reemplazado por

cat "${hosts[@]/%/.out}" >"$outfile"
rm -f "${hosts[@]/%/.out}"
Kusalananda
fuente
Obtengo exactamente la salida que quiero obtener, ¿qué podría salir mal aquí?
sintagma el
2
@ ΔλЛ Si, por ejemplo, el primer host tarda en responder, Processing host1será seguido por Processing host2y la salida de en host2lugar de la salida de host1.
Kusalananda