Запуск нескольких функций bash в фоновом режиме и ожидание их возврата


14

Это простой скрипт, который запускает nvidia-smiкоманду на нескольких хостах и ​​сохраняет ее вывод в общий файл. Цель здесь - заставить его работать асинхронно .

Достаточно ли &в конце process_host()вызова функции? Мой сценарий правильный?

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

Ответы:


13

Да, но ваш вывод может быть искажен. Лучше, чтобы функция записывала свои выходные данные в определенный файл в зависимости от имени хоста, а затем позволяла основному сценарию объединить результат (и очистить).

Кроме того, вы должны двойные кавычки ваших переменных. Скопируйте и вставьте скрипт в ShellCheck .

Может быть, что-то вроде этого:

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

Последний цикл может быть заменен на

cat "${hosts[@]/%/.out}" >"$outfile"
rm -f "${hosts[@]/%/.out}"

Я получаю именно тот результат, который хочу получить, что здесь может пойти не так?
синтагма

2
@ ΔλЛ Если, например, первый хост не отвечает, Processing host1за ним последует Processing host2вывод, host2а не вывод host1.
Кусалананда
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.