2012-10-24 3 views
5

다운로드 URL 목록을 읽는 셸 스크립트를 만들어 계속 사용 중인지 확인하려고합니다. 나는 현재 스크립트에서 무엇이 잘못되었는지 확신하지 못한다. (필자는 이것에 익숙하지 않다.) 포인터가 큰 도움이 될 것이다!Wget이있는 쉘 스크립트 - 다른 루프 내부에 중첩 된 경우

사용자 @ PC를 : ~/테스트 # 고양이 sites.list

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

스크립트 :

#!/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 

그대로, 스크립트가 notok.txt에 모든 출력 - (첫 번째 구글 사이트해야 ok.txt로 이동하십시오.) 내가 실행한다면 : 다음

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

을 그리고 할 : 그것은 아무 문제없이 문자열을 greps

grep "200 OK" wget-log 

. 구문과 관련하여 멍청한 실수가 있었습니까? 감사합니다 m8s!

답변

6

-b 옵션은 wget을 백그라운드로 보내므로 wget이 완료되기 전에 grep을 수행합니다. -b 옵션없이

시도 :

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

좋은 캐치 !! +1 – Graham

+0

사실. 나도 +1. :) – ghoti

+0

작품! 고맙습니다! –

4

당신이 무슨 일을하는지와 몇 가지 문제가 있습니다.

  • for i in에는 공백이 포함 된 줄에 문제가 있습니다. while read을 사용하여 파일의 개별 행을 읽는 것이 더 좋습니다.
  • 변수를 인용하지 않습니다. 파일의 한 줄 (또는 한 줄에있는 단어)이 하이픈으로 시작하면 어떻게 될까요? 그러면 wget이이를 옵션으로 해석합니다. 여기에는 잠재적 인 보안 위험뿐만 아니라 오류가 있습니다.
  • 파일을 만들고 제거하는 것은 정말로 필요하지 않습니다. URL이 도달 가능한지 여부를 확인하기 만하면 임시 파일 및 추가 코드 없이도 URL을 제거 할 수 있습니다.
  • wget이 반드시 최상의 도구는 아닙니다. 대신 curl을 사용하는 것이 좋습니다.

그래서 여기

#!/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" 

이 안된 ...이 처리하는 더 좋은 방법입니다. 교육 목적으로 만 사용됩니다. 너트가 들어있을 수 있습니다.

+1

+1 좋은 교육학적인 노력 –

+0

정말 놀라워요. 정말 도움이됩니다. 고티 감사합니다. –