2012-10-24 18 views
5

Próbuję utworzyć skrypt powłoki, który odczyta listę adresów URL do pobrania, aby sprawdzić, czy nadal są aktywne. Nie jestem pewien, co jest nie tak z moim aktualnym scenariuszem (jestem nowy) i wszelkie wskazówki byłyby ogromną pomocą!Skrypt powłoki z Wget - Jeśli jeszcze zagnieżdżony wewnątrz pętli

użytkownik @ pc: ~/test # cat sites.list

http://www.google.com/images/srpr/logo3w.png 
http://www.google.com/doesnt.exist 
notasite 

Scenariusz:

#!/bin/bash 
for i in `cat sites.list` 
do 
wget --spider $i -b 
if grep --quiet "200 OK" wget-log; then 
echo $i >> ok.txt 
else 
echo $i >> notok.txt 
fi 
rm wget-log 
done 

AS jest skrypt wyprowadza wszystko do notok.txt - (pierwsza strona Google powinien przejdź do ok.txt). Ale jeśli uruchomię:

wget --spider http://www.google.com/images/srpr/logo3w.png -b 

a następnie wykonaj:

grep "200 OK" wget-log 

To greps ciąg bez żadnych problemów. Co popełniłem noob za pomocą składni? Dzięki m8s!

Odpowiedz

6

Opcja -b wysyła wget na tło, więc robisz grep przed zakończeniem wget.

Spróbuj bez opcji -b:

if wget --spider $i 2>&1 | grep --quiet "200 OK" ; then 
+0

dobre złapanie !! +1 – Graham

+0

Rzeczywiście. +1 ode mnie też. :) – ghoti

+0

Działa! Dziękuję Ci! –

4

Istnieje kilka problemów z tym, co robisz.

  • Twój for i in będzie miał problemy z liniami zawierającymi białe znaki. Lepiej używać while read, aby czytać poszczególne wiersze pliku.
  • Nie cytujesz swoich zmiennych. Co jeśli wiersz w pliku (lub słowo w linii) zaczyna się od łącznika? Następnie wget interpretuje to jako opcję. Tutaj masz potencjalne zagrożenie bezpieczeństwa, a także błąd.
  • Tworzenie i usuwanie plików nie jest konieczne. Jeśli wszystko, co robisz, sprawdza, czy adres URL jest osiągalny, możesz to zrobić bez plików tymczasowych i dodatkowego kodu, aby je usunąć.
  • wget niekoniecznie jest najlepszym narzędziem do tego. Radziłbym zamiast tego używać curl.

Więc tutaj jest lepszy sposób, aby sobie z tym poradzić ...

#!/bin/bash 

sitelist="sites.list" 
curl="/usr/bin/curl" 

# Some errors, for good measure... 
if [[ ! -f "$sitelist" ]]; then 
    echo "ERROR: Sitelist is missing." >&2 
    exit 1 
elif [[ ! -s "$sitelist" ]]; then 
    echo "ERROR: Sitelist is empty." >&2 
    exit 1 
elif [[ ! -x "$curl" ]]; then 
    echo "ERROR: I can't work under these conditions." >&2 
    exit 1 
fi 

# Allow more advanced pattern matching (for case..esac below) 
shopt -s globstar 

while read url; do 

    # remove comments 
    url=${url%%#*} 

    # skip empty lines 
    if [[ -z "$url" ]]; then 
    continue 
    fi 

    # Handle just ftp, http and https. 
    # We could do full URL pattern matching, but meh. 
    case "$url" in 
    @(f|ht)tp?(s)://*) 
     # Get just the numeric HTTP response code 
     http_code=$($curl -sL -w '%{http_code}' "$url" -o /dev/null) 
     case "$http_code" in 
     200|226) 
      # You'll get a 226 in ${http_code} from a valid FTP URL. 
      # If all you really care about is that the response is in the 200's, 
      # you could match against "2??" instead. 
      echo "$url" >> ok.txt 
      ;; 
     *) 
      # You might want different handling for redirects (301/302). 
      echo "$url" >> notok.txt 
      ;; 
     esac 
     ;; 
    *) 
     # If we're here, we didn't get a URL we could read. 
     echo "WARNING: invalid url: $url" >&2 
     ;; 
    esac 

done < "$sitelist" 

To niesprawdzone. Tylko do celów edukacyjnych. Może zawierać orzechy.

+1

+1 Miły wysiłek pedagogiczny –

+0

Niesamowite, to jest naprawdę pomocne! Dzięki Ghoti. –

Powiązane problemy