vor kurzem benötigte ich ein Skript um auf einer Reihe von Rechnern per ssh verschiedene Befehle auszuführen.
Ziel war ein Skript, dass zunächst auf jedem der 40 Rechner einen der Aufrufe aus der Liste ausführt und sobald der Rechner fertig ist die restlichen Aufrufe der Reihe nach "nachschiebt", bis alle abgearbeitet sind. Dabei muss und soll nicht darauf gewartet werden bis alle 40 Rechner mit ihrem Auftrag fertig sind sondern jeder soll gleich wieder beschäftigt werden.
Meine Skript funktioniert zwar inzwischen (fast), aber das Problem der "Absprache" zwischen den einzelnen Prozessen ist nicht schön gelöst.
Da mein letztes Posting aus dem ursprüngliche Thread [1] dann etwas off topic war uns sich auch keiner gemeldet hat, versuche ich es hier noch mal.
Mein Skript funktioniert im Prinzip so:
Es wird eine Liste mit auszuführenden Programmaufrufen erstellt und in einen Array (CommandArray)
abgelegt und eine Liste mit den ips von in im Netz erreichbaren Rechnern ermittelt ($ipList). Letzteres mache ich mit "nmap".
Die eigentliche Verwaltung der Jobs mache ich dann über eine Schleife mit der eine Subshell für jede ssh-Verbindung gestartet wird.
Die einzelnen Subshells müssen nun aber wissen welche Jobs schon bearbeitet wurden/werde. Dazu müsste man eine Variable haben auf die alle Subshells lesend und schreibend zugreigen können. Das habe ich aber nicht hinbekommen. Selbst mit "export" bekommt man den Wert der Variable nicht wieder aus der Subshell heraus bevor diese beendet ist. Also nehme ich eine Datei um die Nummer des nächsten zu bearbeitenden Jobs zu speichern.
Code: Alles auswählen
for ip in $ipList
do
(
read < ./jobstoberun JOBSTOBERUN
while [ 1 ] ; do
read < ./jobstoberun JOBSTOBERUN
if [ "$JOBSTOBERUN" -le 0 ]
then
echo "[$JOBSTOBERUN]@$ip: no jobs left"
break
fi
echo $(($JOBSTOBERUN-1)) > ./jobstoberun
echo "[$JOBSTOBERUN]@$ip: ssh -l cgogolin $ip ${CommandArray[$JOBSTOBERUN]}"
ssh -l cgogolin $ip ${CommandArray[$JOBSTOBERUN]}
if [ "$?" != "0" ]; then
echo "[$JOBSTOBERUN]@$ip: job failed or aborted"
echo "${CommandArray[$JOBSTOBERUN]}" >> ./failedjobs.log
break
else
echo "[$JOBSTOBERUN]@$ip: finished"
fi
done
)&
sleep 1
done
wait
Kann man das besser lösen?
[1] http://www.debianforum.de/forum/viewtop ... 19#p613219