404 मिलने के बाद आप 'wget' को कैसे रोकते हैं?


12

यदि आप ब्रेस विस्तार का उपयोग करते हैं wget, तो आप क्रमिक रूप से गिने हुए चित्र आसानी से प्राप्त कर सकते हैं:

$ wget 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg'

यह पहली 10 फाइलों 90.jpgको 99.jpgसिर्फ ठीक करने के लिए लाया गया है, लेकिन 100.jpgबाद में 404 लौटाता है : फ़ाइल को त्रुटि नहीं मिली (मेरे पास सर्वर पर केवल 100 चित्र संग्रहीत हैं)। यदि आप किसी बड़ी श्रेणी का उपयोग करते हैं, तो ये गैर-अस्तित्व वाली फाइलें "समस्या" बन जाती हैं, जैसे कि {00..200}100 गैर-मौजूद फ़ाइलों के साथ, यह स्क्रिप्ट के निष्पादन के समय को बढ़ाता है, और यहां तक ​​कि एक मामूली बोझ (या कम से कम झुंझलाहट) हो सकता है सर्वर।

क्या wgetइसकी 404 त्रुटि प्राप्त होने के बाद इसे रोकने का कोई तरीका है ? (या इससे भी बेहतर, एक पंक्ति में दो, मामले में एक और कारण के लिए एक लापता फ़ाइल थी) उत्तर में ब्रेस विस्तार का उपयोग करने की आवश्यकता नहीं है; लूप भी ठीक हैं।


1
वास्तविक समय के परिदृश्य में, आप स्थिति जानने के लिए प्रत्येक URL को हिट करना चाह सकते हैं। 1, 2 or even n failuresजब आप [begin .. end]सूचकांकों को जानते हैं तो सही तरीका नहीं है । [1..200]जब आप जानते हैं कि आप केवल 100 छवियां हैं, तो आप सीमा क्यों निर्दिष्ट करेंगे [1..100]? मुझे लगता है कि आप parallelप्रक्रिया को गति देने के लिए एक साथ अनुरोध के लिए जीएनयू की कोशिश कर सकते हैं।
स्पार्ककोट

1
@SparKot is कुंजी है मुझे नहीं पता कि सर्वर पर केवल 100 छवियां हैं, मैं चाहता हूं कि स्क्रिप्ट श्रृंखला में जितनी हो सके उतनी छवियों को डाउनलोड करें जब तक कि यह पता नहीं चल गया है कि अंत कहां है।
IQAndreas

जवाबों:


9

यदि आप एक लूप से खुश हैं:

for url in 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg'
do
    wget "$url" || break
done

यह wgetआपके विस्तार में प्रत्येक URL के लिए तब तक चलेगा जब तक कि यह विफल न हो जाए, और फिर breakलूप से बाहर।

यदि आप एक पंक्ति में दो असफलता चाहते हैं तो यह थोड़ा और जटिल हो जाता है:

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कि ऐसा करने के लिए कुछ भी बनाया गया है।


क्या मैं elifदूसरा उदाहरण स्पष्ट करने के लिए उपयोग करने का सुझाव दूं? शायद ऐसा ही कुछ? gist.github.com/IQAndreas/84cae3f0193b67691ff2 (यह केवल एक अतिरिक्त लाइन कहते हैं, डाल सहित नहीं thenके रूप में एक ही लाइन पर रों ifरों)
IQAndreas

काफी उचित। एक-लाइन अनुवाद अब उतना सीधा नहीं है, लेकिन यह वैसे भी बहुत अच्छा नहीं है।
माइकल होमर

9

आप $?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

लूप के लिए थोड़ा साफ किया जा सकता है, लेकिन आप सामान्य विचार को समझ सकते हैं।

बदलने $threshold -eq 16के लिए -eq 24मतलब होगा यह 3 बार असफल होने से पहले ही बंद कर देंगे जाएगा, फिर भी यह एक पंक्ति में दो बार नहीं होगा, यह अगर यह पाश में दो बार विफल रहा होगा।

इसका कारण 16और 24उपयोग किया जाता है जो कि कुल रिटर्न कोड है।
wget प्रतिसाद देता है 8जब यह एक प्रतिक्रिया कोड प्राप्त करता है जो सर्वर से एक त्रुटि से मेल खाता है, और इस प्रकार 16कुल 2 त्रुटियां हैं।

जब असफलता केवल एक पंक्ति में दो बार होती है तो रोकना थ्रेशोल्ड को रीसेट करके किया जा सकता है जब भी wgetसफल होता है, अर्थात जब रिटर्न कोड 0 होता है


Wget रिटर्न कोड की एक सूची यहां मिल सकती है - http://www.gnu.org/software/wget/manual/html_node/Exit-Status.html


2
हालांकि यह जवाब से निष्कर्ष निकाला जा सकता है, आप स्पष्ट रूप से करते रहे कि एक 404 त्रुटि के एक निकास कोड देता है चाहते हो सकता है 8, इसलिए जादू संख्या के 16और 24
IQAndreas

1
मैंने अपना उत्तर
लॉरेंस

1
के लिए धन्यवाद $?! बहुत उपयोगी!
neverMind9

2

GNU समानांतर के साथ यह काम करना चाहिए:

parallel --halt 1 wget ::: 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg'

संस्करण 20140722 से आप अपने "लगभग एक पंक्ति में दो" हो सकते हैं - विफलता: - 2% नौकरियों के 2% के लिए असफल होने की अनुमति देगा:

parallel --halt 2% wget ::: 'http://www.iqandreas.com/sample-images/100-100-color/'{90..110}'.jpg'

1

IMO, wget'के एक्जिट कोड / स्टेटस' पर ध्यान केंद्रित करते हुए कुछ उपयोग-मामलों के लिए बहुत भोला हो सकता है, इसलिए यहाँ एक है जो HTTP स्थिति कोड के साथ-साथ कुछ दानेदार निर्णय लेने पर विचार करता है।

wgetकमांड -S/--server-responseपर HTTP रिस्पांस हेडर्स को प्रिंट करने के लिए एक ध्वज प्रदान करता है 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

-1

अजगर में आप कर सकते हैं

from subprocess import *

def main():
    for i in range(90, 110):
       try :
          url = "url/"+str(i)
          check_output(["wget", url])
       except CalledProcessError:
          print "Wget returned none zero output, quiting"
          sys.exit(0)

यदि आप अधिक https://docs.python.org/2/library/subproc.html.html करना चाहते हैं तो सबप्रोसेस के लिए दस्तावेज़ चेकआउट करें


जब तक check_outputकुछ जादू wgetका पता लगाने के लिए चारों ओर 404- मैं नहीं मानता कि यहां पर्याप्त जांच हो रही है और इसलिए वास्तव में इस सवाल का जवाब नहीं है।
शालम्ब

यह डॉक्स को पढ़ता है। यह stdout या stderr में आउटपुट की जाँच करता है। wget के पास 404
briankip
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.