最終更新以降に変更された場合にのみ、http経由でファイルをダウンロードします


20

HTTPサーバーからファイルをダウンロードする必要がありますが、それは前回ダウンロードしたときから変更された場合のみです(If-Modified-Sinceヘッダー経由など)。また、ディスク上のファイルにカスタム名を使用する必要があります。

Linuxでこのタスクに使用できるツールは何ですか?


wget -Nで使用できないため、使用-Nできません-O


ファイルをダウンロードして名前を変更してみませんか?
ジュリアンナイト

..ツールは、最後のダウンロード以降にHTTPリソースが変更されたかどうかを確認できる必要がありますか?これは、ファイルの名前が変更されており、ツールが期待する場所にもう存在しない場合、困難になります。
cweiske

申し訳ありませんが、私はそのコメントを急いで、私の答えを参照してください。
ジュリアンナイト

回答:


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コマンドを使用して正しい名前の「ファイル」にリンクするハードリンクを作成します。リンクされたファイルには、元のファイルと同じメタデータがあります。

唯一の制限は、ファイルシステムの境界を越えてハードリンクを作成できないことです。


多くの目的では、iノードのIDが実際に質問者にとって重要でない限り、シンボリックリンクで十分かもしれません。
トビースパイト

1
wgetは、この仕事に適したツールです。タイムスタンプとファイルサイズをチェックしますが、curl(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:)
ジョンオックスリー

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.