Schlagwort-Archive: Unix

Eine Reihe von IP-Adressen per Ping prüfen

Mitunter hat man das Problem, eine nicht kleine Anzahl an Rechnern auf Erreichbarkeit zu überprüfen. Die Adressen und Hostnamen liegen als Excel-Liste vor, aber diese alle von Hand zu pingen … dazu bin ich echt zu faul. Also habe ich mir ein kleines Script gebaut, welches diese Aufgabe elegant erledigt:

#!/bin/sh
#
# Sendet einen Ping an alle in der übergebenen Datei aufgeführten Adressen.
# In der Liste muss pro Zeile zuerst die IP-Adresse und danach durch Leerzeichen
# getrennt der Hostname stehen (optional).
# Die Ausgabe von Ping kann unterdrückt werden, indem STDERR ins Null-Dev
# geschickt wird:
# ping_list liste.txt 2>/dev/null
#

#set -x

Newline='
'

IFS=$Newline
for LINE in `cat $1`
do
  #echo "'$LINE'"
  ADR=${LINE%% *}
  HOST=${LINE##* }
  #echo "Adr: $ADR"
  #echo "Host: $HOST"
  if [ "$OSTYPE" = "linux" ]
  then
    ping -q -W 3 -c 1 $ADR 1>&2
  elif [ "$OSTYPE" = "hpux11.00" ]
  then
    ping $ADR -n 1 -m 3 1>&2
  else
    echo "Unknown OS"
    exit 99
  fi
  if [ $? -eq 0 ]
  then
    echo "$ADR ($HOST) is up"
  else
    echo "$ADR ($HOST) FAILED"
  fi
done
IFS=

Es arbeitet zzt. unter Linux (SuSE 11.1) und HP-UX 11i und kann auch hier heruntergeladen werden:
ping_list

Dateien eines Jahres archivieren

Heute stand ich (mal wieder) vor der Aufgabe, in einem Verzeichnis alle Dateien vom Vorjahr zu archivieren.

Im Artikel „Dateien an Hand des Datums und der Uhrzeit finden“ habe ich gezeigt, wie man mit find Dateien eines bestimmten Zeitraums finden kann. Da ich aber für die Archivierung keine Rekursion benötige, kann ich das Ganze etwas einfacher mit einem Einzeiler machen:

stat -c '%n Date:%y' * | perl -n -e 'print "$1
" if /^(.+)sDate:2008/' \n | zip archiv_2008.zip -@

Ich verwende hier stat, um das Ausgabeformat bestimmen zu können. Da die Dateinamen Leerzeichen enthalten können, kann ich keine Leerzeichen als Trenner zwischen Name und Datum verwenden, daher die Kennzeichnung mittels „Date:“. Perl filtert mir erstens alle Dateien von 2008 heraus und gibt auch nur den Dateinamen aus. Zip liest diese von der Standardeingabe, wenn die Dateiliste als -@ angegeben ist.

Soll Zip die Dateien auch gleich entsorgen, so kann man das über die Option -m erreichen.

Alle Fehlermeldungen in einem Script umleiten

Man kann in einem Shell-Script ja Ausgaben, die an den Standard-Fehler-Kanal STDERR gehen, mit 2>>dateiname.log in eine Datei umleiten. Dies muss aber für jeden Befehl einzeln gemacht werden. Es gibt aber bei der Bash eine Methode, die Umleitung für das gesamte Script zu machen.

Dazu nutzt man eine Spezialform des Befehls exec: Werden als Parameter nur Umleitungen angegeben, so leitet die Shell die gewünschten Kanäle permanent um.

#!/bin/bash
exec 2>> dateiname.log

echo "Normale Ausgabe"
echo "An stderr" >&2
echo "das folgende macht einen Fehler"
TEST=`gibtsnicht  `
echo "Das geht auch in Pipes:"
LINES=`lsx -1 $TREE | egrepx -v '^.+$' | wc -l`

Startet man das Script, so erhält man auf der Konsole diese Ausgabe:

Normale Ausgabe
das folgende macht einen Fehler
Das geht auch in Pipes:

Das sind die Ausgaben auf der Standard-Ausgabe.

Die Log-Datei enthält die Ausgabe der Fehlermeldungen:

An stderr
./logtest: line 7: gibtsnicht: command not found
./logtest: line 9: lsx: command not found
./logtest: line 9: egrepx: command not found

Sollen alle Ausgaben in die Logdatei umgeleitet werden, so verwendet man

exec >> dateiname.log 2>&1

Das Quartal mit date berechnen

Das Unix-Kommando date kennt viele Format-Parameter aber leider keinen, der uns das Quartal ausgibt. Zum Glück lässt sich das aber mit Hilfe von expr berechnen.

Wir können mit dem date-Befehl einen Ausdruck erstellen, den expr dann für uns ausrechnet. Wir bekommen das das aktuelle Quartal oder, wenn wir mit -d ein anders angeben, das des gefragten Datums:

expr `date "+( %m - 1 ) / 3 + 1"`

expr `date -d "2007-05-01" "+( %m - 1 ) / 3 + 1"`

Dateien an Hand des Datums und der Uhrzeit finden

Manchmal muss man eine Datei finden, von der man nur weiß, wann sie zuletzt geändert wurde. Weiß man, dass das vor 3 Tagen war, hilft einem die Option -mtime +3 des Befehls find. Hat man aber ein Datum und eine Uhrzeit, muss man ein wenig tricksen.

Man kann hier die Option -newer zusammen mit einer Referenzdatei verwenden. Diese Referenzdatei kann mit touch erstellt werden. Da wir einen bestimmten Zeitpunkt suchen, brauchen wir noch eine zweite Referenzdatei, da -newer sonst alle neueren Dateien ausgibt.

$ touch -t 11142104 /tmp/tmp_start
$ touch -t 11142105 /tmp/tmp_end
$ find /opt -newer /tmp/tmp_start ! -newer /tmp/tmp_end

Dies findet Dateien im Verzeichnis /opt und darunter, die zuletzt am 14.November um 21:04 Uhr modifiziert wurden.

Dieses Beispiel funktioniert unter Linux, aber auch unter HP-UX, dessen Befehle find und touch leider nicht so viele Optionen kennen wie die Linux-Versionen

Dateinamen mit Leerzeichen auf der Kommandozeile verarbeiten

Dateinamen, die Leerzeichen enthalten, machen auf der Kommandozeile oder in Scripten häufig Ärger, da das Leerzeichen meist als Trennzeichen zwischen den Parametern dient. hier nun ein paar Tricks, wie man die Probleme umschiffen kann.

Will man beispielsweise untersuchen, wieviel Platz die Dateien und Unterverzeichnisse des aktuellen Verzeichnisses jeweils einnehmen, kann man das mit

ls -A -1 | du -sh

machen. Aber das funktioniert nur für Dateinamen und Verzeichnisse, die keine Leerzeichen enthalten. Um auch solche zu verarbeiten muss man die folgende Kommandokette verwenden:

find . -maxdepth 1 -print0 | xargs -0 du -sh

Wir benutzen hier find, weil dieses die gefunden Namen durch das Argument -print0 als sog. nullterminierten String ausggeben kann. Dies teilen wir xargs mit dem Schalter -0 mit, wodurch xargs automatisch alle Leerzeichen etc. escaped an das eigentliche Kommando „du -sh“ weitergibt. Damit find nicht auf die Idee kommt, auch die Unterverzeichnisse zu durchsuchen, begrenzen wir die Suche mit „-maxdepth 1“ auf das angegebene Verzeichnis.

Unter Linux (bzw. mit GNU-ls) kann man auch die Option -Q des ls Kommandos nutzen, welches die Namen in Anführungszeichen setzt. Xargs ist aber trotzdem erforderlich:

/bin/ls -A1Q | xargs du -sh

[Wird fortgesetzt…]