unduh file melalui http hanya jika diubah sejak pembaruan terakhir


20

Saya perlu mengunduh file dari server HTTP, tetapi hanya jika itu berubah sejak terakhir kali saya mengunduhnya (mis. Melalui If-Modified-Sincetajuk). Saya juga perlu menggunakan nama khusus untuk file di disk saya.

Alat apa yang dapat saya gunakan untuk tugas ini di linux?


wget -Ntidak dapat digunakan karena -Ntidak dapat digunakan dengan -O.


Mengapa tidak mengunduh file lalu mengganti namanya?
Julian Knight

.. karena alat masih harus dapat memeriksa apakah sumber daya HTTP berubah sejak unduhan terakhir? Ini akan sulit jika file telah diubah namanya dan dengan demikian tidak ada lagi di tempat yang diharapkan alat itu.
cweiske

Maaf, saya bergegas komentar itu, lihat jawaban saya.
Julian Knight

Jawaban:


26

Pertimbangkan untuk menggunakan curldaripada wget:

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

man curl mengatakan:

-z/ --time-cond <ekspresi tanggal>

(HTTP / FTP) Minta file yang telah dimodifikasi lebih lambat dari waktu dan tanggal yang diberikan, atau yang telah dimodifikasi sebelum waktu itu. Ekspresi tanggal dapat berupa segala jenis string tanggal atau jika tidak cocok dengan string internal, ia mencoba mendapatkan waktu dari nama file yang diberikan.

Jika $filebelum tentu ada sebelumnya, Anda harus menggunakan -zflag yang bersyarat, menggunakan test -e "$file":

if test -e "$file"
then zflag="-z '$file'"
else zflag=
fi
curl -o "$file" $zflag "$uri"

(Perhatikan bahwa kami tidak mengutip ekspansi di $zflagsini, karena kami ingin itu mengalami pemisahan ke 0 atau 2 token).

Jika shell Anda mendukung array (mis. Bash), maka kami memiliki versi yang lebih aman dan bersih:

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

7

Switch wget -Nhanya mendapatkan file jika telah berubah sehingga pendekatan yang mungkin dilakukan adalah dengan menggunakan -Nsaklar sederhana yang akan mendapatkan file jika perlu tetapi meninggalkannya dengan nama yang salah. Kemudian buat tautan keras menggunakan ln -Pperintah untuk menautkannya ke "file" dengan nama yang benar. File yang ditautkan memiliki metadata yang sama dengan aslinya.

Satu-satunya batasan adalah Anda tidak dapat memiliki tautan keras melintasi batas-batas sistem file.


Untuk banyak tujuan, tautan simbolik mungkin memadai - kecuali jika identitas inode benar-benar penting bagi penanya.
Toby Speight

1
wget adalah alat yang lebih baik untuk pekerjaan ini. Ia memeriksa timestamp DAN ukuran file, yang curl (7.38.0) tidak. Juga, wget berakhir dengan non-0 pada 4xx / 5xx, sedangkan curl tidak terlalu peduli dengan kode server secara default.
schieferstapel

4

Skrip Python 3.5+ untuk membungkus perintah curl:

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 (),
))

Ini luar biasa! TIL chain:)
John Oxley

1

Pendekatan yang mirip dengan " tanggal cek " (dengan "curl - time-cond"), akan mengunduh sesuai dengan perbandingan ukuran file, yaitu Unduh hanya jika file lokal memiliki ukuran yang berbeda dari file jarak jauh .

Ini berguna misalnya, ketika proses pengunduhan gagal di tengah , dan dengan demikian file yang diunduh lokal mendapatkan tanggal yang lebih baru daripada file jarak jauh, tetapi sebenarnya rusak, dan pengunduhan ulang diperlukan:

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

Opsi "curl -z / --time-cond" (yang disarankan di jawaban lain) tidak akan mengunduh file jarak jauh dalam kasus ini (karena file lokal memiliki tanggal yang lebih baru), tetapi skrip " pemeriksaan ukuran " ini akan!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.