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でガンガン落としてると画像が破損してる事が多い。そこで、ImageMagickのidentify
を使うことにした。
実際に使ってみた結果、画像サーバがエラー吐いて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"
汚いが、ワンライナーでダウンロードが途中で止まってダウンロードに失敗しているか確認できる。