Как Вы останавливаете 'wget' после того, как это получит 404?

Необходимо создать репозиторий на основе пакетов. Можно легко сделать это с dpkg-scanpackages, например:

dpkg-scanpackages . /dev/null | gzip > Packages.gz
echo "deb file:/path/to/directory ./" > /etc/apt/sources.list.d/local-mirror.list
apt-get update

Это позволит Вам использовать файлы от своего локального зеркала. Поскольку более подробный пример взглянул на Ubuntu персональное руководство репозитория.

12
23.07.2014, 01:36
5 ответов

Если вы довольны циклом:

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

Это запустит wget для каждого URL в вашем расширении до тех пор, пока не произойдет сбой, а затем прервёт из цикла.

Если вы хотите, чтобы два сбоя подряд, это становится немного сложнее:

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

Вы можете немного уменьшить это с помощью && и || вместо , если , но это становится довольно уродливым.

Я не верю, что wget имеет для этого что-то встроенное.

9
27.01.2020, 19:55

Вы можете использовать переменную $? , чтобы получить код возврата 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 можно немного почистить, но общую идею можно понять.

Изменение $порогового значения -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.
9
27.01.2020, 19:55

С помощью GNU Parallel это должно работать:

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

Начиная с версии 20140722, вы можете получить свои "два подряд" - Failure: --halt 2% позволит выполнить 2% заданий:

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

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
3
27.01.2020, 19:55

В питоне можно сделать

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/subprocess.html

-1
27.01.2020, 19:55

Теги

Похожие вопросы