마지막 업데이트 이후 변경된 경우에만 http를 통한 파일 다운로드


20

HTTP 서버에서 파일을 다운로드해야하지만 마지막으로 다운로드 한 이후 (예 : If-Modified-Since헤더 를 통해 ) 파일이 변경된 경우에만 해당됩니다 . 또한 디스크에있는 파일의 사용자 지정 이름을 사용해야합니다.

Linux에서이 작업에 어떤 도구를 사용할 수 있습니까?


wget -N때문에 사용할 수 없습니다 -N와 함께 사용할 수 없습니다 -O.


파일을 다운로드 한 다음 이름 바꾸지 않겠습니까?
Julian Knight

.. 도구가 마지막 다운로드 이후에 HTTP 리소스가 변경되었는지 여전히 확인할 수 있어야합니까? 파일 이름이 변경되어 도구가 예상하는 위치에 더 이상 존재하지 않는 경우 이는 어려울 것입니다.
cweiske

미안, 나는 그 의견을 서두르고 내 대답을 참조하십시오.
Julian Knight

답변:


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"

( $zflag0 또는 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의 정체성이 실제로 asker에 중요하지 않다면, 상징적 인 링크가 적절할 수 있습니다.
Toby Speight

1
이 작업에는 wget이 더 나은 도구입니다. 컬 (7.38.0)이 아닌 타임 스탬프와 파일 크기를 확인합니다. 또한 wget은 4xx / 5xx에서 0이 아닌 것으로 종료되는 반면 curl은 기본적으로 서버 코드를 신경 쓰지 않습니다.
schieferstapel

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:)
John Oxley

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"옵션은이 경우 원격 파일을 다운로드하지 않지만 (로컬 파일의 날짜가 더 최신이므로)이 " 크기 확인 "스크립트는

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.