題 僅在上次更新後更改時才通過http下載文件


我需要從HTTP服務器下載文件,但是只有在我上次下載它之後它才發生變化(例如通過 If-Modified-Since 頭)。我還需要為我的磁盤上的文件使用自定義名稱。

我可以在linux上使用什麼工具來完成這項任務?


wget -N 不能用,因為 -N 不能用 -O


11
2018-04-30 19:55


起源


為什麼不下載文件和 然後 重命名嗎? - Julian Knight
..因為該工具仍然需要能夠檢查自上次下載以來HTTP資源是否發生了變化?如果文件已重命名,那麼這將很難,因此在工具所需的位置不再存在。 - cweiske
對不起,我趕緊發表評論,看看我的回答。 - Julian Knight


答案:


考慮使用 curl 代替 wget

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

man curl 說:

-z/--time-cond  <date expression>

(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個令牌)。


13
2018-05-01 12:16





wget開關 -N 只有在文件發生變化時才獲取文件,因此可能的方法是使用簡單文件 -N 如果需要,將獲取文件,但保留錯誤名稱的開關。然後使用the創建一個硬鏈接 ln -P 命令將其鏈接到具有正確名稱的“文件”。鏈接文件具有與原始文件相同的元數據。

唯一的限制是您不能跨文件系統邊界擁有硬鏈接。


6
2018-05-01 08:11



出於許多目的,符號鏈接可能是足夠的 - 除非inode身份對提問者來說實際上很重要。 - Toby Speight
wget是這項工作的更好工具。它檢查時間戳和文件大小,curl(7.38.0)沒有。此外,wget在4xx / 5xx上以非0終止,而curl默認情況下並不真正關心服務器代碼。 - schieferstapel


用於包裝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 (),
))

3
2017-12-23 08:51



這太棒了! TIL chain :) - John Oxley