
Мне нужно загрузить файл с 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