仅当自上次更新以来已更改时才通过http下载文件


20

我需要从HTTP服务器下载文件,但前提是该文件自上次下载以来已发生更改(例如,通过If-Modified-Since标头)。我还需要为磁盘上的文件使用自定义名称。

我可以在Linux上使用什么工具来完成此任务?


wget -N无法使用,因为-N不能与一起使用-O


为什么不下载文件然后重命名?
朱利安·奈特

..因为该工具仍需要检查自上次下载以来HTTP资源是否已更改?如果文件已被重命名,因此在工具期望的位置不再存在,这将很难。
cweiske

抱歉,我急于发表评论,请看我的回答。
朱利安·奈特

Answers:


26

考虑使用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"

7

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

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


对于许多目的来说,符号链接可能就足够了-除非inode身份对于发问者而言实际上很重要。
Toby Speight

1
wget是完成这项工作的更好工具。它检查时间戳和文件大小,而curl(7.38.0)不会。另外,wget在4xx / 5xx上以非0终止,而curl默认情况下并不真正在乎服务器代码。
schieferstapel's

4

用于包装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 (),
))

这太棒了!TIL chain:)
约翰·奥克斯利

1

与“ 日期检查 ”(带有“ curl --time-cond”)类似的方法是根据文件大小比较进行下载,即仅在本地文件的大小与远程文件的大小不同时下载

例如,当下载过程在中间失败时很有用,因此本地下载文件的日期比远程文件的日期新,但实际上它已损坏,因此需要重新下载:

local_file_size=$([[ -f ${FILE_NAME} ]] && wc -c < ${FILE_NAME} || echo "0")
remote_file_size=$(curl -sI ${FILE_URL} | awk '/Content-Length/ { print $2 }' | tr -d '\r' )

if [[ "$local_file_size" -ne "$remote_file_size" ]]; then
    curl -o ${FILE_NAME} ${FILE_URL}
fi

在这种情况下,“ curl -z / --time-cond”选项(在另一个答案中建议)将不会下载远程文件(因为本地文件的日期更新),但是此“ size check ”脚本会下载!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.