У меня есть 1000 удаленных машин. Я хочу запустить некоторые определенные команды на всех из них, но параллельно. Я использую эти команды, которые запускаются последовательно:
for f in `cat host.lst`
do
./runScript.sh $f
done
Предположим, host.lst
содержит 100 хостов. Я хочу запустить runScript.sh
на 100 хостах параллельно. Также необходимо вести журналы.
Я не могу установить ни одну утилиту на свой компьютер, например PSSH
.
Я провел много исследований и нашел эти ссылки, но они не помогли. Я не понимаю, как они работают:
Автоматически запускать команды по SSH на многих серверах
Выполнить команду для нескольких файлов, соответствующих шаблону, параллельно
Может ли кто-нибудь объяснить логику?
решение1
logdir=`mktemp -d`
bunch=200
IFS=$'\n'
for hosts in $(< hosts.lst xargs -r -L "$bunch"); do
IFS=" ";
for host in $hosts; do
ssh -n -o BatchMode=yes "$host" './runScript.sh' 1>"$logdir/$host.log" 2>&1 &
done
wait
done
Предположим, что в файле перечислены тысячи (тысячи) хостов по одной строке hosts.lst
, а затем из них за один раз выбирается группа (200), и на каждом из этих 200 хостов создается ваше runScript.sh
использование ssh
, batch mode
и в то же время сохраняется stdout+stderr
вывод от каждого из этих фоновых заданий в файл с именем host
в каталоге $logdir
, который можно просматривать по мере необходимости.
Наконец, мы ждем, пока одна группа не закончится, прежде чем запустить следующую группу с помощью команды wait
в конце внутреннего for
цикла.
решение2
Следующая модификация вашего скрипта, не требующая никаких других утилит, будет выполняться параллельно, но может столкнуться с ограничениями в зависимости от ограничений ваших хостов на открытые дескрипторы файлов:
for f in $(cat host.lst); do
./runScript.sh $f &
done
Чтобы записать результаты в журнал, просто добавьте > run.log
после done
, чтобы сохранить в новом файле run.log
.
Ключевым изменением является добавление &
, которое запускает процесс в фоновом режиме, а не ждет его завершения перед выполнением следующей команды.