Запуск декількох функцій 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.
Kusalananda
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.