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

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}"

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.