Tengo miles de máquinas remotas. Quiero ejecutar algunos comandos específicos en todos ellos, pero en paralelo. Utilizo estos comandos que se ejecutan secuencialmente:
for f in `cat host.lst`
do
./runScript.sh $f
done
Supongamos que host.lst
contiene 100 hosts. Quiero ejecutar runScript.sh
100 hosts en paralelo. Además, se deben mantener registros.
No puedo instalar ninguna utilidad en mi máquina como PSSH
.
Investigué mucho y encontré estos enlaces, pero no me ayudaron. No entiendo como funcionan:
Ejecute automáticamente comandos a través de SSH en muchos servidores
Ejecutar comando en múltiples archivos que coincidan con un patrón en paralelo
¿Alguien puede explicar la lógica?
Respuesta1
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
Suponiendo que los miles (miles) de hosts se enumeran en una/línea en el hosts.lst
archivo y luego de estos se seleccionan un grupo de una sola vez (200), y en cada uno de estos 200 hosts se generan su runScript.sh
uso ssh
y batch mode
al mismo tiempo preservan el stdout+stderr
arrojando cada uno de estos trabajos en segundo plano en un archivo con el nombre de host
en el directorio $logdir
, que puede examinarse cuando sea necesario.
Finalmente esperamos a que termine un grupo antes de lanzar el siguiente, mediante el wait
comando al final del for
bucle interno.
Respuesta2
La siguiente modificación de su secuencia de comandos, que no requiere ninguna otra utilidad, se ejecutará en paralelo, pero puede tener límites dependiendo de las limitaciones de sus hosts en cuanto a identificadores de archivos abiertos:
for f in $(cat host.lst); do
./runScript.sh $f &
done
Para capturar los resultados en un registro, simplemente agregue > run.log
after done
para guardarlos en un archivo nuevo run.log
.
El cambio clave es la adición de &
, que ejecuta un proceso en segundo plano en lugar de esperar a que se complete antes de ejecutar el siguiente comando.