
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"
(ここでは の展開を引用符で囲まないことに注意してください。0$zflag
または 2 のトークンに分割する必要があるためです)。
シェルが配列をサポートしている場合 (例: 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