我需要从 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