僅在上次更新後發生更改時才透過 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

相關內容