wget で content-Lengthとか status codeをgrepする

わかってるんだ curl の方が優れてるのは

curl はHTTP/2に対応し、絶賛時代遅れ感が否めないwget

そんなcurlに唯一対抗できる素晴らしい機能が、フォルダを指定してダウンロードできる-Pオプションと、ファイルスキップ機能-nc

いや、まあ if [ ! -f file]; then curl -o file; fi;すれば良いだけの話だし、file=$path/$(basename url);すれば良いやんけ、と思う方も居るかと思うが、xargs でワンライナーすると結構きつい。

ここ最近、自分の5年以上使ってきたプログラミング言語を半年以上使わずシェルスクリプトだけで毎日送ってる。xargsとparallelが便利なんや。研究の為に書いたら、すっげぇ汚いコードになってて、諦めてシェルスクリプトに戻った。

画像破損チェックでImageMagickのidentify使うのはよろしくない

そんで、200万ファイル以上の画像をクローンしてこいってなった時、wgetでガンガン落としてると画像が破損してる事が多い。そこで、ImageMagickidentifyを使うことにした。

apple.stackexchange.com

実際に使ってみた結果、画像サーバがエラー吐いてHTMLとか出力すると、画像でないファイルが出来上がる。 画像でないファイルをidentifyに読み込ませると、stderrに出力しやがる。

identify-im6.q16: insufficient image data in file `1049768/file.jpg' @ error/jpeg.c/ReadJPEGImage/1039.

つまり以下のコードは画像じゃないファイルだと動かない

find . -type f | xargs -I@ -n1 bash -c "if identify @ | grep Corrupt; then rm @ fi";

で画像でも、wgetの途中で接続が切れた画像ファイルでも反応しなかった。!?

本題のwget で content-Lengthとか status codeをgrepする

じゃあ、wget の レスポンスヘッダのContent-Lengthで確認しよう。というのが本題。

wget -q --server-response --spider URLするとstderrに出力される !? なぜだ*

なのでstderrをpipeに送る為に 2>&1を入れる

あとはレスポンスヘッダが200なのと、Content-Lengthが入ってるのを確認する。 ついでに下4行をwhileの中にブチ込んでも良い。

response="$(wget -q --server-response --spider URL 2>&1 )";
# " "外すと改行が消されます
if test $(echo $response | grep -Eq 'HTTP[^ ]+ 200') -a $(echo $response | grep -q 'Content-Length'); then
  echo $(echo $response | grep -oE 'Content-Length: [0-9]+' | grep -oE '[0-9]+');
fi

結果は 11451みたいな自然数が出力される

*なぜだ
後日かんがえてたら、答えがでた。
wget で保存しながら、サーバステータスをパイプできる。
wget -q --server-response -O test.zip http://localhost/test.zip 2>&1 | grep -oE 'Content-Length: [0-9]+' | grep -oE '[0-9]+' | xargs -n1 -I% bash -c "if [ $(ls -la test.zip | gawk -F' ' '{print $5}') = % ]; then echo 'download size match!'; fi" 汚いが、ワンライナーでダウンロードが途中で止まってダウンロードに失敗しているか確認できる。