仅当自上次更新后发生变化时才通过 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 个标记)。

如果你的 shell 支持数组(例如 Bash),那么我们有一个更安全、更干净的版本:

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

答案2

wget 开关-N仅在文件发生变化时才获取文件,因此一种可能的方法是使用简单开关,-N它会在需要时获取文件,但会留下错误的名称。然后使用命令创建硬链接,将ln -P其链接到具有正确名称的“文件”。链接文件具有与原始文件相同的元数据。

唯一的限制是您不能跨文件系统边界拥有硬链接。

答案3

用于包装 curl 命令的 Python 3.5+ 脚本:

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

相关内容