Datei nur über http herunterladen, wenn sie seit dem letzten Update geändert wurde

Datei nur über http herunterladen, wenn sie seit dem letzten Update geändert wurde

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-SinceHeader). 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 -Nkann nicht verwendet werden, da -Nnicht zusammen verwendet werden kann -O.

Antwort1

Erwägen Sie die Verwendung curlvon wget:

curl -o "$file" -z "$file" "$uri"

man curlsagt:

-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 $filedies nicht unbedingt bereits vorhanden ist, müssen Sie die Verwendung der -zFlagge 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 -Nruft die Datei nur ab, wenn sie geändert wurde. Ein möglicher Ansatz wäre daher, den einfachen -NSchalter 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 -Pum 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

verwandte Informationen