Samstag, 13. Februar 2010

Über den richtigen Umgang mit wget

Aufgabe: Nächtliches Abholen einer großen Datei von einem Webserver.
Problem: Der Webserver hustet, die DSL-Leitung möchte gerade nicht - also alle möglichen Arten von Störungen. Wer will daneben sitzen bleiben?

Ein einfaches wget [URL] kam nicht in Betracht... Lösung: Man baue wget in eine Schleife ein. Diese überprüfe den Rückgabewert, warte im Falle eines (beliebigen) Fehlers und versuche das ganze erneut:
while ! wget http://example.org/; do sleep 600; done
Da aber auch eine begonnene Übertragung abbrechen kann macht es Sinn, diese wieder aufzunehmen. Dafür gibt es die Option -c:
while ! wget -c http://example.org/;
do sleep 600;
done
So sieht das aus und ist, da es ein "Einzeiler" ist, auch als Cron-Job oder at-Job gut zu verwenden. Möglicherweise sollten Ausgaben noch nach /dev/null umgeleitet werden.
while ! wget -c http://example.org/ 1> /dev/null 2> /dev/null;
do sleep 600;
done
Der Wert hinter sleep gibt die Anzahl der Sekunden an, die gewartet wird. Ich hielt 600, also 10 Minuten, für sinnvoll. Gelegentlich macht es Sinn, den Speicherort festzulegen. Dies besorgt die Option -O
while ! wget -cO /tmp/example.org_index \
http://example.org/ 1> /dev/null 2> /dev/null;
do sleep 600;
done
Verwendung als Batch-Datei: (hole_url, am besten in ~/bin/hole_url):
#! /bin/sh
echo -e "\n\n";

if ! test -n "$1"; then
echo "Fatal: Keine Quelle angegeben.
Rufen Sie das Skript mit der Angabe einer Dateiquelle auf.
Beispiel: $0 \"http://example.org/\"
Sie können auch ein Ziel angeben.
Beispiel: $0 \"http://example.org/\" \"/tmp/index\"
";
exit;
fi

username=`whoami`;
skriptname=`echo $0 | tr -d '[:cntrl:]' | tr -d './|'`;
lockfile="/tmp/$username-$skriptname-lockfile";

if ! test -f $lockfile;
then touch $lockfile;
fi

aktiv=`grep "$1" $lockfile|wc -l`;

if test "0" != "$aktiv"; then
echo "Fatal: Für die Ressorce \"$1\" besteht bereits ein Auftrag.
Wenn Sie der Auffassung sind, dass dies nicht zutreffend ist,
dann löschen Sie den Eintrag in $lockfile.

Das Programm wird mit Fehlercode 1 beendet.
";
exit 1;
fi

if test -z "$2"; then
echo $1 >> $lockfile;
while ! wget -c "$1" 1>> ~/wget.log 2>> ~/wget.log; do
sleep 600;
done
echo -e "Die Ressource \"$1\" wurde geholt und gespeichert.\n\n";
lockfileInhhalt=`grep -v "$1" $lockfile`;
echo $lockfileInhhalt > $lockfile;
exit 0;
fi

if test -x "$2"; then
echo "Fatal: Das Ziel \"$2\" existiert bereits und ist ausführbar.
Dieses Programm weigert sich aus gutem Grund ausführbare Dateien zu
überschreiben.

Das Programm wird mit Fehlercode 2 beendet.
";
exit 2;
fi

if test -f "$2" ;then
if test ! -w "$2"; then
echo "Fatal: Das Ziel \"$2\" kann nicht geschrieben werden.
Lösung: Überprüfen Sie die Rechte.

Das Programm wird mit Fehlercode 3 beendet.
";

fi
fi

if test "force" != "$3" -a "continue" != "$3"; then
if test -f $2; then
echo "Fatal: Das Ziel \"$2\" existiert bereits.
* Wenn Sie das Ziel überschreiben wollen geben sie als drittes
Argument \"force\" an.
* Wenn Sie einen abgebrochenen Download fortsetzen wollen,
geben sie als drittes Argument \"continue\" an.
Beispiel: \"$0 $1 $2 force\"

Das Programm wird mit Fehlercode 4 beendet.
";
exit 4;
fi

else

if test -f "$2" -a "force" = "$3"; then
echo "Das Ziel \"$2\" wird gelöscht.";
rm -- "$2";
fi

echo -e "Die Ressource \"$1\" wurde geholt und
als \"$2\" gespeichert.\n\n";
fi

echo $1 >> $lockfile;

while ! wget -cO "$2" "$1" 1>> ~/wget.log 2>> ~/wget.log;
do
sleep 600;
done
lockfileInhhalt=`grep -v "$1" $lockfile`;
echo $lockfileInhhalt > $lockfile;
exit 0;

Letzte Aufgabe: bestimmter Zeitpunkt:

Ist der at-Dienst aktiv (feststellbar mit ps -C atd) kann natürlich mit
echo "hole_url http://example.org/" | at 0400
auch am nächsten Morgen ab 4 Uhr versucht werden die Datei zu holen.

Keine Kommentare:

Kommentar veröffentlichen