Sonntag, 26. April 2009
Suchbegriffe aus Apache Logfile
Zur Suchmaschinenoptimierung gehört zuallererst die Diagnose:
Mit welchen Suchbegriffen kommen die Leute auf welche meiner Seiten. Die (Google-)Suchbegriffe sind Teil des Refererstrings im Apache Logfile. Das ist aber im Allgemeinen lang und unübersichtlich.
Folgendes Bashskript extrahiert die gewünschten Daten aus Logfiles.
Voraussetzung: Leserechte auf das Logfile (z.B. access_log).
Mit welchen Suchbegriffen kommen die Leute auf welche meiner Seiten. Die (Google-)Suchbegriffe sind Teil des Refererstrings im Apache Logfile. Das ist aber im Allgemeinen lang und unübersichtlich.
Folgendes Bashskript extrahiert die gewünschten Daten aus Logfiles.
Voraussetzung: Leserechte auf das Logfile (z.B. access_log).
"Suchbegriffe aus Apache Logfile" vollständig lesen
Samstag, 18. April 2009
Geolocation Wrapper Skript für die Bash
Geolocation oder Geotargeting ist das Schließen auf den geographischen Standort aus einer IP-Adresse. Zwar kann wegen dynamisch zugeteilter IP's, der Verwendung von NAT oder Proxis usw., die Zuordnung nie 100%-ig genau sein, meist kommt man aber ungefähr in die richtige Richtung (Provider, Netz...).
Für besonders Neugierige gibt es auch die Möglichkeit, die IP nicht nur einem Land, sondern einer Stadt zuzuordnen (incl. Längen- und Breitengrad). http://www.maxmind.com/, wo das Projekt GeoIP zuhause ist, bietet zum Beispiel online so einen Dienst an. Noch praktischer wäre natürlich ein lokales Shellskript.
Und so wirds gemacht:
Für besonders Neugierige gibt es auch die Möglichkeit, die IP nicht nur einem Land, sondern einer Stadt zuzuordnen (incl. Längen- und Breitengrad). http://www.maxmind.com/, wo das Projekt GeoIP zuhause ist, bietet zum Beispiel online so einen Dienst an. Noch praktischer wäre natürlich ein lokales Shellskript.
Und so wirds gemacht:
"Geolocation Wrapper Skript für die Bash" vollständig lesen
Sonntag, 22. März 2009
Headless Firefox als "HTML-to-PDF"
CSS Anweisungen wie "@media print" werden meines Wissens nur von Browsern umgesetzt. Ich selbst verwende üblicherweise in meinen Stylesheets irgendwo untendran so Dinge wie:
Die Browser wiederum brauchen immer einen Xserver und der ist auf Webservern nicht verfügbar. Außerdem ist ein Browser selten so ausgelegt, dass etwas ohne Usereingabe funktioniert.
Ich habe aber tatsächlich eine Lösung gefunden:
Xvfb + Firefox3 + Extension CommandLinePrint
Der Vorteil dieser Lösung ist neben der vollen CSS Unterstützung, dass Firefox (mit Cairo) vollwertige PDF's erzeugt, die zur Langzeitarchivierung geeignet sind (Text als Text, eingebundene Schriften).
Xvfb ersetzt den Xserver für Firefox.
@media print { #navi {display:none} }Es ist nicht sinnvoll, das Menü mit auszudrucken. Schade um den Platz. Nur können Programme wie htmldoc oder pisa oder html2ps wenig bis gar kein CSS. Das macht eine automatisierte Arichvierung in PDF Files in schöner, sinnvoller und dem Original entsprechender Form schwierig.
Die Browser wiederum brauchen immer einen Xserver und der ist auf Webservern nicht verfügbar. Außerdem ist ein Browser selten so ausgelegt, dass etwas ohne Usereingabe funktioniert.
Ich habe aber tatsächlich eine Lösung gefunden:
Xvfb + Firefox3 + Extension CommandLinePrint
Der Vorteil dieser Lösung ist neben der vollen CSS Unterstützung, dass Firefox (mit Cairo) vollwertige PDF's erzeugt, die zur Langzeitarchivierung geeignet sind (Text als Text, eingebundene Schriften).
Xvfb ersetzt den Xserver für Firefox.
"Headless Firefox als "HTML-to-PDF"" vollständig lesen
Dienstag, 17. März 2009
Zeichen ersetzen
In der Shell gibt es immer mehrere Wege zum Ziel. Zeichen oder Substrings ersetzen kann man z.B. entweder mit sed oder der Bash selbst. Was zum Beispiel öfter mal benötigt wird, ist das Ersetzen von Leerzeichen in Variablen, damit sie als Teil eines Linuxpfades dienen können.
Leerzeichen ersetzen:
Nur hinten ersetzen:
Auch praktisch an der Bashmethode ist die Möglichkeit, die Ersetzung nur am Anfang (#) oder Ende (%) durchzuführen.
Voranstellen:
Man könnte auch etwas voranstellen.
Welche Methode die bessere ist, hängt vom Kontext ab. Keine Frage, sed ist bei weitem vielseitiger, aber für so einfache Dinge wie hier gezeigt, ist eine Subshell (wie sed sie öffnen würde) gar nicht nötig.
Ein Nachteil der Bashmethode: sie funktioniert nur mit Variablen, um etwas in einem beliebigen Text zu ersetzen, ist sed geeigneter.
Leerzeichen ersetzen:
var="hallo welt und so weiter"; echo ${var// /_}
Mit sed sähe das dann so aus:var="hallo welt und so weiter"; echo $var | sed -e 's/ /_/g'
Ergebnis bei beiden: hallo_welt_und_so_weiterNur hinten ersetzen:
Auch praktisch an der Bashmethode ist die Möglichkeit, die Ersetzung nur am Anfang (#) oder Ende (%) durchzuführen.
var="txtdatei-txt.txt"; echo ${var/%txt/html}
Mit sed geht das natürlich auch:var="txtdatei-txt.txt"; echo $var | sed 's/txt$/html/'
Ergebnis bei beiden: txtdatei-txt.htmlVoranstellen:
Man könnte auch etwas voranstellen.
var="einedatei.txt"; echo ${var/#/bak_}
Das selbe Beispiel mit sed:var="einedatei.txt"; echo $var | sed 's/^/bak_/'
Erbebnis bei beiden: bak_einedatei.txtWelche Methode die bessere ist, hängt vom Kontext ab. Keine Frage, sed ist bei weitem vielseitiger, aber für so einfache Dinge wie hier gezeigt, ist eine Subshell (wie sed sie öffnen würde) gar nicht nötig.
Ein Nachteil der Bashmethode: sie funktioniert nur mit Variablen, um etwas in einem beliebigen Text zu ersetzen, ist sed geeigneter.
Samstag, 14. März 2009
Formatieren mit Bashbuiltin printf
Wie man Zahlenkolonnen mit (g)awk formatiert, wurde im Beitrag Zahlenkolonnen-formatieren-mit-gawk.html schon gezeigt. Wenn es nur um die Formatierung geht, und nicht gerechnet werden muss, geht das noch einfacher mit dem Bashbuiltin printf.
Die Ausgangsdatei fürs erste Beispiel sei die "datei.txt":
Was es mit den Anweisungen "%7.2f" usw. auf sich hat, lest bitte im oben genannten gawk-Beitrag nach (oder in der Manpage zu "sprintf"). Dann muss ich das hier nicht wiederholen. Gerundet wird übrigens korrekt.
In der "datei2.txt" werden Punkte als Kommazeichen verwendet. Damit die Zahlen korrekt als solche erkannt werden, mein $LANG ist ja "de_DE.UTF-8", muss ich also die zuständige Umgebungsvariable setzen:
Die Ausgangsdatei fürs erste Beispiel sei die "datei.txt":
13,5 556,987 14,56 13,1 15,356 345,2 16,106 2,7 17,1 3,99 18,41 4,342 19,14 345,2 20,21 20,1 21,18 4,5 22,01 77,2 23,1 94,627Diese unordentliche Liste von Fließkommazahlen kann schön formatiert werden mit:
cat datei.txt | while read line; do printf "%7.2f -> %7.2f\n" $line; done
Immer vorausgesetzt, dass eure Umgebungsvariable $LANG bzw. $LC_NUMERIC mit den in der Datei verwendeten Kommazeichen (Punkt oder Beistrich) übereinstimmt. Ist das nicht der Fall, gibt printf die Fehlermeldung "...invalid number" aus. Was es mit den Anweisungen "%7.2f" usw. auf sich hat, lest bitte im oben genannten gawk-Beitrag nach (oder in der Manpage zu "sprintf"). Dann muss ich das hier nicht wiederholen. Gerundet wird übrigens korrekt.
In der "datei2.txt" werden Punkte als Kommazeichen verwendet. Damit die Zahlen korrekt als solche erkannt werden, mein $LANG ist ja "de_DE.UTF-8", muss ich also die zuständige Umgebungsvariable setzen:
"Formatieren mit Bashbuiltin printf" vollständig lesen
Skriptoptionen mit getopts
Viele Shellprogramme haben Optionen, die das Verhalten des Programmes anpassen. Aber wie wird sowas umgesetzt? Am einfachsten mit dem Bashbuiltin getopts (nicht zu verwechseln mit dem Programm "getopt", das etwas Ähnliches macht).
Ein einfaches Beispiel: ein Skript mit vier Optionen.
Sollen sich die Optionen gegenseitig ausschließen, muss das extra geprüft werden. Z.B. mit einem Counter:
Ein einfaches Beispiel: ein Skript mit vier Optionen.
#!/bin/bash
usage="Usage: ein Hilfetext..."
while getopts "abch" options; do
case $options in
a ) echo 'option -a gesetzt';;
b ) echo 'option -b gesetzt';;
c ) echo 'option -c gesetzt';;
h ) echo $usage
exit 0
;;
\? ) echo $usage
exit 1
;;
esac
done
Obiges Skript hat vier Optionen -a, -b, -c und -h für einen Hilfetext. Alle Optionen dürfen gleichzeitig gesetzt werden, auch mehrfach und zwar immer in beliebiger Reihenfolge. Keine der Optionen erfordert einen Parameter. Nur wenn eine unbekannte Option, etwa -x gesetzt wird, tritt ein Fehler auf, das Skript wird dann sofort beendet und ein kleiner Hilfetext ausgegeben.usage="Usage: ein Hilfetext..."
while getopts "abch" options; do
case $options in
a ) echo 'option -a gesetzt';;
b ) echo 'option -b gesetzt';;
c ) echo 'option -c gesetzt';;
h ) echo $usage
exit 0
;;
\? ) echo $usage
exit 1
;;
esac
done
Sollen sich die Optionen gegenseitig ausschließen, muss das extra geprüft werden. Z.B. mit einem Counter:
"Skriptoptionen mit getopts" vollständig lesen
Samstag, 31. Januar 2009
SNMP hrSystemDate.0 Datumsformat anpassen
Mit snmpget kann mit "HOST-RESOURCES-MIB::hrSystemDate.0" die Systemzeit eines Hosts abgefragt werden.
Das Problem ist das Ausgabeformat, mit dem kein anderes Programm etwas anfangen kann.
Ein Beispiel: 2009-1-31,12:1:3.0,+1:0
Für Menschen ist es lesbar, aber an date und co. kann man das so nicht übergeben, deshalb...
Zum Einsatz kommt (mal wieder) printf, das die einstelligen Monat, Tag, usw. -Ausgaben vorne mit "0" auffüllt.
Das Problem ist das Ausgabeformat, mit dem kein anderes Programm etwas anfangen kann.
Ein Beispiel: 2009-1-31,12:1:3.0,+1:0
Für Menschen ist es lesbar, aber an date und co. kann man das so nicht übergeben, deshalb...
#!/bin/bash
# snmp Datumstring Format anpassen
remote_ip="127.0.0.1"
commun="public"
# das Datum ueber snmp holen
rdatestring=$( snmpget -v1 -c $commun $remote_ip HOST-RESOURCES-MIB::hrSystemDate.0 | gawk '{print $NF}' )
# den String aufteilen in Datum und Zeit
rdate=$( echo $rdatestring | gawk -F',' '{print $1}' )
rtime=$( echo $rdatestring | gawk -F',' '{print $2}' | gawk -F'.' '{print $1}' )
# das Format korrigieren (Monat, Tag, Stunde,... zweistellig)
cldate=$( echo $rdate | gawk -F'-' '{printf("%4i",$1)}; {printf("%02i",$2)}; {printf("%02i",$3)};' )
cltime=$( echo $rtime | gawk -F':' '{printf("%02i",$1)}; {printf("%02i",$2)}; {printf(" %02i",$3)};' )
# Timestamp mit date
rdate_s=$( date -d "$cldate $cltime sec" +%s )
echo $rdate_s
$rdate_s ist ein Unix Timestamp, mit dem dann z.B. gerechnet oder etwas verglichen werden kann.# snmp Datumstring Format anpassen
remote_ip="127.0.0.1"
commun="public"
# das Datum ueber snmp holen
rdatestring=$( snmpget -v1 -c $commun $remote_ip HOST-RESOURCES-MIB::hrSystemDate.0 | gawk '{print $NF}' )
# den String aufteilen in Datum und Zeit
rdate=$( echo $rdatestring | gawk -F',' '{print $1}' )
rtime=$( echo $rdatestring | gawk -F',' '{print $2}' | gawk -F'.' '{print $1}' )
# das Format korrigieren (Monat, Tag, Stunde,... zweistellig)
cldate=$( echo $rdate | gawk -F'-' '{printf("%4i",$1)}; {printf("%02i",$2)}; {printf("%02i",$3)};' )
cltime=$( echo $rtime | gawk -F':' '{printf("%02i",$1)}; {printf("%02i",$2)}; {printf(" %02i",$3)};' )
# Timestamp mit date
rdate_s=$( date -d "$cldate $cltime sec" +%s )
echo $rdate_s
Zum Einsatz kommt (mal wieder) printf, das die einstelligen Monat, Tag, usw. -Ausgaben vorne mit "0" auffüllt.
« vorherige Seite
(Seite 7 von 11, insgesamt 74 Einträge)
» nächste Seite