
Ich muss eine Datei von einem HTTP-Server herunterladen, aber nur, wenn sie sich seit dem letzten Download geändert hat (z. B. über den If-Modified-Since
Header). Außerdem muss ich für die Datei auf meiner Festplatte einen benutzerdefinierten Namen verwenden.
Welches Tool kann ich für diese Aufgabe unter Linux verwenden?
wget -N
kann nicht verwendet werden, da -N
nicht zusammen verwendet werden kann -O
.
Antwort1
Erwägen Sie die Verwendung curl
von wget
:
curl -o "$file" -z "$file" "$uri"
man curl
sagt:
-z
/--time-cond
<Datumsausdruck>(HTTP/FTP) Fordern Sie eine Datei an, die nach der angegebenen Uhrzeit und dem angegebenen Datum geändert wurde oder die vor dieser Zeit geändert wurde. Der Datumsausdruck kann alle möglichen Datumszeichenfolgen enthalten oder, wenn er mit keiner internen übereinstimmt, versucht er stattdessen, die Zeit aus einem angegebenen Dateinamen abzurufen.
Wenn $file
dies nicht unbedingt bereits vorhanden ist, müssen Sie die Verwendung der -z
Flagge mithilfe von Folgendem bedingt machen test -e "$file"
:
if test -e "$file"
then zflag="-z '$file'"
else zflag=
fi
curl -o "$file" $zflag "$uri"
(Beachten Sie, dass wir die Erweiterung hier nicht in Anführungszeichen setzen $zflag
, da wir möchten, dass sie in 0 oder 2 Token aufgeteilt wird).
Wenn Ihre Shell Arrays unterstützt (z. B. Bash), haben wir eine sicherere und sauberere Version:
if test -e "$file"
then zflag=(-z "$file")
else zflag=()
fi
curl -o "$file" "${zflag[@]}" "$uri"
Antwort2
Der wget-Schalter -N
ruft die Datei nur ab, wenn sie geändert wurde. Ein möglicher Ansatz wäre daher, den einfachen -N
Schalter zu verwenden, der die Datei bei Bedarf abruft, sie aber mit dem falschen Namen belässt. Erstellen Sie dann mit dem Befehl einen Hardlink, ln -P
um ihn mit einer „Datei“ mit dem richtigen Namen zu verknüpfen. Die verknüpfte Datei hat dieselben Metadaten wie das Original.
Die einzige Einschränkung besteht darin, dass Sie keine Hardlinks über Dateisystemgrenzen hinweg haben können.
Antwort3
Python 3.5+-Skript zum Umschließen des Curl-Befehls:
import argparse
import pathlib
from subprocess import run
from itertools import chain
parser = argparse.ArgumentParser()
parser.add_argument('url')
parser.add_argument('filename', type=pathlib.Path)
args = parser.parse_args()
run(chain(
('curl', '-s', args.url),
('-o', str(args.filename)),
('-z', str(args.filename)) if args.filename.exists() else (),
))
Antwort4
Ich habe verschiedene Dinge mit wget probiert und konnte das Abschneiden der Ausgabe nicht verhindern, ohne " -N " zu verwenden.
Stattdessen können Sie Ihren eigenen -if-modified-Header erstellen und abgeschnittene Dateien durch Backups ersetzen.
OUTFILE="some.thing"
IF_MOD_DATE=`date "+%a, %d %b %Y %T %Z" -r $OUTFILE`
IF_MOD_HEADER="If-Modified-Since: $IF_MOD_DATE"
cp $OUTFILE backup_$OUTFILE
wget -O $OUTFILE --header="$IF_MOD_HEADER" "http://your.tld/resource"
# if files is truncated, replace with backup
[ -s $OUTFILE ] || { rm $OUTFILE && mv backup_$OUTFILE $OUTFILE ; }
# remove any backup and ignore complaints of missing files.
rm backup_$OUTFILE 2>&1