check_url
Et appendix til mit foredrag man
wget.
Da jeg sad og forberedte foredraget om wget kom jeg ind på
problemet med at wget
ignorerer kommentarafmærkning i HTML-dokumenter. Derfra var der
ikke særlig langt til at jeg fik lyst til at skrive et program til at
undersøge om en URL peger på en eksisterende resource.
Her følger programmet med mine kommentarer og forklaringen:
#!/bin/tcsh |
Vi bruger kommandofortolkeren /bin/tcsh. På nogle systemer
finder man tcsh i kataloget /usr/bin/. Hvis
det er tilfældet skal linien ændres så den stadigvæk peger på
tcsh.
#-------------------------------------------------------- #-- Check parameter: if ( "$1" == "") then echo "Programmet kræver et HTTP URL som argument." exit 1 endif |
Vi undersøger om det første kommandolinieargument ($1) er
en tom streng. Det er vi ikke interesserede i.
#-------------------------------------------------------- #-- Split parameter: set protokol=`echo $1 | cut -d':' -f1` |
Kommandoen mellem de "baglæns" apostroffer (`) udføres og
det der kommer ud sættes i stedet for de "baglæns" apostroffer (og
teksten mellem dem).
echo $1 sender kommandolinieargumentet ud på
stdout, der sendes videre (|) til cut.
cut er et nyttigt lille værktøj der tager en fil (eller
stdin) og nøjes med at skrive udvalgte søjler ud igen.
-d efterfulgt af et tegn i anførselstegn angiver hvilket
tegn der bruges som skilletegn mellem søjlerne. Her har vi valgt kolon
(:). -f efterfulgt af en liste med søjlenumre
(komma og bindestreg kan bruges som man almindeligvis gør det) angiver
hvilke søjler der skal udskrives. Her har vi valgt kun at udskrive
første søjle, det vil sige alt før det første kolon.
Hvis $1 er http://jacob.sparre-andersen.dk/ vil
resultatet af kommandoen mellem de "baglæns" apostroffer altså være
http, så det svarer til at der stod
set protokol=http, hvilket sætter variablen
protokol til http.
set maskine=`echo $1 | cut -d':' -f2- | cut -d'/' -f3` |
Her tager vi anden søjle og udad ved kolon-opdelingen
(-f2-) og sender videre til endnu et eksemplar af
cut der bruger skråstreger som skilletegn (-d'/')
og udskriver tredie søjle (-f3).
Hvis vi bruger samme eksempel som før sender den første
cut-kommando teksten //hugin.risoe.dk/Jacob/ videre
til den næste cut-kommando der klipper
hugin.risoe.dk ud (det tomme felt før den første skråstreg
tæller også som en søjle). Det svarer altså til at der stod
set maskine=hugin.risoe.dk på denne linie.
set resource=/`echo $1 | cut -d':' -f2- | cut -d'/' -f4-` |
Denne linie ligner den forrige, men her udskrives fjerde søjle og udad ved skråstregsopdelingen, og så står der en skråstreg foran det hele.
Hvis vi fortsætter med samme eksempel som før bliver resultatet af
kommandoerne i "baglæns" apostroffer Jacob/, hvilket
svarer til at der stod set resource=/Jacob/ på denne
linie.
#-------------------------------------------------------- #-- Prøv telnet: if ( "$protokol" == "http" ) then |
Vi kan kun håndtere HTTP-protokollen.
( echo "HEAD $resource HTTP/1.0"; \
echo ""; \
sleep 10s ) \
|
Her starter vi en midlertidig kommandofortolker, der skriver en HTTP-forespørgsel (for eksempel HTTP /Jacob/ HTTP/1.0) og venter ti sekunder. Semikoloner (;) bruges til at adskille kommandoer og bagstreger (\) bruges til at markere at næste linie er en del af denne linie.
| telnet $maskine 80 \
|
Hele resultatet fra den midlertidige kommandofortolker sendes videre til en
telnet-opkobling på web-serverens port nummer 80.
|& grep HTTP > /tmp/HTTP-resultat
|
Her samler vi almindeligt output (kendt som "stdout") og
fejlmeddelelser ("stderr") og sorterer alle linier der ikke
indeholder teksten "HTTP" fra. Resten skrives til en midlertidig fil.
set resultat=`cut -d" " -f2- /tmp/HTTP-resultat` |
Her kører vi cut med mellemrum som skilletegn og skriver hele
den midlertidige fil, bortset fra første søjle ud. Den midlertidige fil
vil her typisk indeholde en enkelt linie med teksten "HTTP 200 OK", så variablen kommer til at indeholde teksten "200 OK".
echo $protokol\://$maskine$resource $resultat |
Her skriver vi URL'en og resultatet fra HTTP-forespørgslen ud. I stedet
for at samle et URL af de enkelte dele kunne man jo egentlig bare bruge
$1. På den anden side kan vi på denne måde se at
opdelingen i protokol, maskine og resource fungerer.
else echo "Ukendt protokol." exit 2 endif |
Hvis det er en anden protokol meddeler vi det lige.
#-------------------------------------------------------- |
Man kan enten bare kalde check_url direkte fra
kommandolinien:
~/> check_url http://jacob.sparre-andersen.dk/ http://jacob.sparre-andersen.dk/ 200 OK ~/> check_url ftp://ftp.sslug.dk/SSLUG-folder.tgz Ukendt protokol. ~/> |
Man kan også lave en fil med URL'er og køre check_url med
hvert af URL'erne:
~/> cat testdata http://jacob.sparre-andersen.dk/ http://www.sslug.dk/ http://www.sslug.dk/~sparre/ ~/> foreach url ( `cat testdata` ) foreach? check_url $url foreach? end http://jacob.sparre-andersen.dk/ 200 OK http://www.sslug.dk/ 200 OK http://www.sslug.dk/~sparre/ 403 Forbidden ~/> |
Var det noget med en kopi af
check_url?
Denne side vedligeholdes af Jacob Sparre Andersen (<jacob@jacob-sparre.dk>), der også gerne
besvarer spørgsmål om check_url.