次のように中括弧拡張を使用すると、順番に番号付けされたwget
画像を簡単に取得できます。
$ wget 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg'
番号付きの最初の10個の90.jpg
ファイルをインポート99.jpg
し、100.jpg
404: ファイルが見つかりません{00..200}
エラー(私のサーバーには100個の画像しか保存されていません)。増やしてサーバーに多少の負担になることもあります。少なくとも問題があります)。
wget
最初の404エラーが発生した後に停止する方法はありますか? (または他の理由でファイルが範囲内で失われる場合は、連続して2つの方が良いです。)答えには、中括弧拡張を使用する必要はありません。
答え1
ループに満足している場合:
for url in 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg'
do
wget "$url" || break
done
wget
これは失敗するまで拡張のすべてのURLに対して実行され、break
ループを終了します。
連続して2回の失敗が予想されると、状況はより複雑になります。
for url in 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg'
do
if wget "$url"
then
failed=
elif [ "$failed" ]
then
break
else
failed=yes
fi
done
&&
使用して||
少し縮小できますが、if
本当に見苦しくなります。
wget
私はこれを行うことが組み込まれていると信じていません。
答え2
この$?
変数を使用してwgetの戻りコードを取得できます。ゼロ以外の場合はエラーが発生したことを意味し、しきい値に達するまでそれを計算してからループから外れることがあります。
こんな感じです。
#!/bin/bash
threshold=0
for x in {90..110}; do
wget 'http://www.iqandreas.com/sample-images/100-100-color/'$x'.jpg'
wgetreturn=$?
if [[ $wgetreturn -ne 0 ]]; then
threshold=$(($threshold+$wgetreturn))
if [[ $threshold -eq 16 ]]; then
break
fi
fi
done
forループは少し整理できますが、一般的なアイデアを得ることができます。
$threshold -eq 16
停止する前に3回失敗するという意味に変更されました-eq 24
。ただし、連続して2回ではなく、ループで2回失敗すると失敗します。
16
sumを使用する理由24
は、戻りコードの合計であるためです。 wgetはサーバーからエラーに対応する応答コードを受け取ると戻り
コードで応答するため、合計2つのエラーが発生します。8
16
失敗が連続して 2 回だけ発生した場合、停止するには、wget
成功時にしきい値をリセットします (例: 戻りコードが 0 の場合)。
wget戻りコードのリストはここにあります。http://www.gnu.org/software/wget/manual/html_node/Exit-Status.html
答え3
終了コード/ステータスに焦点を当てたIMOは、いくつかのwget
ユースケースではあまりにも素直である可能性があるため、ここではいくつかの詳細な決定とともにHTTPステータスコードも考慮されます。
wget
コマンドのHTTP応答ヘッダーを-S/--server-response
印刷するためのフラグを提供します。そのヘッダーを抽出して作業できます。STDERR
#!/bin/bash
set -eu
error_max=2
error_count=0
urls=( 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg' )
for url in "${urls[@]}"; do
set +e
http_status=$( wget --server-response -c "$url" 2>&1 )
exit_status=$?
http_status=$( awk '/HTTP\//{ print $2 }' <<<"$http_status" | tail -n 1 )
if (( http_status >= 400 )); then
# Considering only HTTP Status errors
case "$http_status" in
# Define your actions for each 4XX Status Code below
410) : Gone
;;
416) : Requested Range Not Satisfiable
error_count=0 # Reset error_count in case of `wget -c`
;;
403) : Forbidden
;&
404) : Not Found
;&
*) (( error_count++ ))
;;
esac
elif (( http_status >= 300 )); then
# We're unlikely to reach here in case of 1XX, 3XX in $http_status
# but ..
exit_status=0
elif (( http_status >= 200 )); then
# 2XX in $http_status considered successful
exit_status=0
elif (( exit_status > 0 )); then
# Where wget's exit status is one of
# 1 Generic error code.
# 2 Parse error
# - when parsing command-line options, the .wgetrc or .netrc...
# 3 File I/O error.
# 4 Network failure.
# 5 SSL verification failure.
# 6 Username/password authentication failure.
# 7 Protocol errors.
(( error_count++ ))
fi
echo "$url -> http_status: $http_status, exit_status=$exit_status, error_count=$error_count" >&2
if (( error_count >= error_max )); then
echo "error_count $error_count >= $error_max, bailing out .." >&2
exit "$exit_status"
fi
done
答え4
私がうまく使用したのは
wget 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg' 2>&1 | grep -q 'ERROR 404: Not Found'
grep -q
入力で 404 エラー・メッセージ・パターンを参照し、表示されるとすぐに終了します。読み取れなくなったパイプwget
に書き込もうとすると、SIGPIPE信号が受信されます。grep
実際、wget
最初の404エラーを受け取った直後に終了します。