загрузить файл через http только если он был изменен с момента последнего обновления

загрузить файл через http только если он был изменен с момента последнего обновления

Мне нужно загрузить файл с HTTP-сервера, но только если он изменился с момента последней загрузки (например, через заголовок If-Modified-Since). Мне также нужно использовать пользовательское имя для файла на моем диске.

Какой инструмент я могу использовать для этой задачи в Linux?


wget -Nне может быть использован, так как -Nне может использоваться с -O.

решение1

Рассмотрите возможность использования curlвместо wget:

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

man curlговорит:

-z/--time-cond <выражение даты>

(HTTP/FTP) Запрос файла, который был изменен позже указанного времени и даты, или тот, который был изменен до этого времени. Выражение даты может быть любыми типами строк даты или, если оно не соответствует ни одной внутренней строке, оно пытается получить время из указанного имени файла.

Если $fileне обязательно существует заранее, вам нужно сделать использование флага -zусловным, используя test -e "$file":

if test -e "$file"
then zflag="-z '$file'"
else zflag=
fi
curl -o "$file" $zflag "$uri"

(Обратите внимание, что мы не приводим здесь расширение $zflag, поскольку хотим, чтобы оно подверглось разделению на 0 или 2 токена).

Если ваша оболочка поддерживает массивы (например, Bash), то у нас есть более безопасная и чистая версия:

if test -e "$file"
then zflag=(-z "$file")
else zflag=()
fi
curl -o "$file" "${zflag[@]}" "$uri"

решение2

Переключатель wget -Nполучает файл только в том случае, если он был изменен, поэтому возможным подходом было бы использование простого -Nпереключателя, который получит файл, если это необходимо, но оставит его с неправильным именем. Затем создайте жесткую ссылку с помощью команды ln -P, чтобы связать его с «файлом» с правильным именем. Связанный файл имеет те же метаданные, что и оригинал.

Единственное ограничение заключается в том, что нельзя иметь жесткие ссылки, выходящие за границы файловой системы.

решение3

Скрипт Python 3.5+ для оборачивания команды curl:

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 (),
))

решение4

Я пробовал разные вещи с wget, но не смог остановить обрезание вывода, если не использовать «-N».

Вместо этого вы можете подготовить свой собственный заголовок -if-modified и заменить усеченные файлы резервными копиями.

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

Связанный контент