Newbe Hilfe bei einem kleinen Script

Soon5

FreeBSD Neueinsteiger
Hallo,

Ich mochte gerne ein kleines Programm/Script auf meinem FreeBSD Server installieren, das in regelmässigen Abständen zwei IP Adressen anpingt, und dann einen Konsolen befehl ausführt, wenn beide nicht zu erreichen sind. Das Programm soll dann weiterhin im Hintergrund versuchen die 2 Adressen zu pingen und einen 2. Befehl ausführen, wenn beide wieder erreichbar sind. Dann weiterpingen... Also ne endlosschleife.

Ich denke mal, das das nicht so schwierig ist, aber für jemanden der sich damit nicht auskennt schon.

Danke für Tips und eure Hilfe.

MfG

Soon5
 
Code:
if ping -c 1 host 2>/dev/null >/dev/null ; then
 do irgendwas
else
 do irgendwasanderes
fi

Einfach weiter ausbauen und anpassen. Die Manpage Deiner Shell weiss mehr darueber.
 
Code:
reachable() {
while ping -c1 host 1 && ping -c 1 host2; do
# nada
end
# Verbindung abgebrochen
command1
unreachable
}

unreachable() {
while ! ping -c1 host 1 && ping -c 1 host2; do
# nada
end
# Verbindung wieder da
command2
reachable
}

reachable
Ist ungetestet, kann das so funktionieren?
 
Nein. Sieh Dir das Script mal an und wirf einen Blick in die Manpage der Shell.
> while ping -c1 host 1 && ping -c 1 host2; do

Wieso "while" und wieso "&&"? Wenn ping "keinen Host findet", dann ist der exit-Status != 0; ergo wird der Ping auf host2 nicht ausgefuehrt.
Code:
hellfire# ping -c 1 heise.de.invalid && ping -c 1 heise.de
ping: unknown host: heise.de.invalid
hellfire#

Code:
# nada
end
# Verbindung abgebrochen
command1
unreachable
}
Was soll das sein? Was bedeutet "end"?

Code:
# Host anpingen und die Ausgabe von STDOUT und STDERR nach
# /dev/null schicken.
if ping -c 1 host 2>/dev/null >/dev/null ; then
 # Wenn von "host" ein ping zurueck kommt, dann mache "irgendwas"
 do irgendwas
# Wenn nicht, dann mache "irgendwasanderes"
else
 do irgendwasanderes
fi

Wenn Du mehrere Hosts anpingen und dementsprechend darauf reagieren willst, nimm fping(8) (liegt unter /usr/ports/net rum) und frag den exit-Status ab
Code:
# Mit dem "echo" uebergebe ich fping die Host aus STDIN
hellfire# echo "heise.de\ngoogle.de" | fping -c 1 -q
# Beide Hosts sind erreichbar.
heise.de  : xmt/rcv/%loss = 1/1/0%, min/avg/max = 121/121/121
google.de : xmt/rcv/%loss = 1/1/0%, min/avg/max = 128/128/128
# Der exit-Status == 0; d. h. das letzte Kommando wurde erfolgreichs 
# beendet.
hellfire# echo $?
0
# Hier werden fping die Hosts wieder aus STDIN gegeben, aber diesmal
# ist google.de.invalid nicht erreichbar.
hellfire# echo "heise.de\ngoogle.de.invalid" | fping -c 1 -q
heise.de : xmt/rcv/%loss = 1/1/0%, min/avg/max = 62.2/62.2/62.2
# und schon ist der exit-Status != 0
hellfire# echo $?                                           
2
hellfire#
 
Hier ein kleines Perl-Script:

#!/usr/bin/perl

$rueck1 = 0;
$rueck2 = 0;
$nicht_erreichbar = 0;

while(1) {
sleep 50;
$rueck1 = system "ping -c 1 $ARGV[0] 2>/dev/null > /dev/null";
$rueck2 = system "ping -c 1 $ARGV[1] 2>/dev/null > /dev/null";

if( $nicht_erreichbar == 1 && $rueck1 == 0 && $rueck2 == 0) {
system "$ARGV[3] 2>/dev/null > /dev/null";
}

$nicht_erreichbar = 0;

if($rueck1 != 0 || $rueck2 != 0) {
$nicht_erreichbar = 1;
system "$ARGV[2] 2>/dev/null > /dev/null";
}

}


Ok, das Programm wird so aufgerufen: $SCRITNAME $Adresse1 $Adresse2 $Kommando1 $Kommando2

Ich habe das Zeitintervall auf 50 gesetzt.
Viel Spass.
 
Also, mein Script funktioniert natuerlich, ich hatte mich nur mit "end" vertan, muss natuerlich "done" heissen (wohl zuviel Ruby programmiert).

Das Problem mit der Stackrekursion besteht aber weiterhin (weiss jedoch nicht, wie genau /bin/sh das handhabt).

Ausserdem ist ein ping-count von 1 wohl nicht sehr dolle...
Hier nochmal eine funktionierende Version, btw, ich gehe davon aus, das DNS aufgeloest werden kann, auch wenn der Host offline ist (warum sollte das auch nicht gehen?)

Code:
#!/bin/sh

reachable() {
  while ping -qc1 host1 >/dev/null && ping -qc1 host2 >/dev/null; do
    sleep 3
  done
  echo "unreachable!"
  unreachable
}

unreachable() {
  while ! ping -qc1 host1 >/dev/null && ping -qc1 host2 >/dev/null; do
    sleep 3
  done
  echo "reachable again!"
  reachable
}

reachable
 
und dann einen Konsolen befehl ausführt, wenn beide nicht zu erreichen sind.

So wie ich das verstehe, will er erst ein Kommando ausfuehren, wenn *beide* nicht erreichbar sind. Bei obigen function()'en wird unreachable() ausgefuehrt, wenn nur ein Host nicht erreichbar ist.
 
@strcat: Ganz einfach s/&&/||/

Der Sinn ist mir aber nicht ganz klar. Zumal die Erreichbarkeit eines Dienstes nicht mit ping(8) gemessen wird! :rolleyes:
 
Also,

Hintergrund ist, dass ich mit einem Kumpel zusammen ein WLAN über 2 Häuser aufgebaut habe, das sich eine DSL Leitung teilt (DSL ist beim Kumpel). Der kleine Bruder von meinem Kumpel spielt jetzt gerne im Internet, und wenn ihm der Ping zu schlecht ist, geht er her und steckt den Access Point der WLAN Bridge aus. Damit hab ich kein Inet mehr. Mit dem Script will ich verhindern, das er das macht, weil das Script seine IP am Router sperrt, sobald er die APs aussteckt (dann hat er auch kein Inet mehr). Geht natürlich nur, weil er zu unerfahren ist um die IP zu ändern, oder sich direkt einzuwählen (Er kennt das Passwort eh nicht).

Am Rande, ich hab mal ne andere Frage. besteht die möglichkeit einen Shell Befehl x Minuten nach dem booten auszuführen (Also nach dem booten z.B. 10 min Warten dann Shell befehl ausführen). Der Befehl ist einmalig, muss also nur einmal ausgeführt werden.

Hintergrund. Ich hab eine externe Festplatte am laufen. Wenn ich die gleich beim booten über fstab mounte geht es nicht (bekomme Fehler, rechner stürzt ab). Wenn ich sie so 3 min nach dem booten manuell mounte gehts ohne Probleme (kein Plan warum, ist aber so).

Danke für die Hilfe.

MfG

Soon5
 
hmm..-.
ich glaube, das ap problem kriegst du auch ohne coden hin.
einfach ne familienpackung gaffatape kaufen und wahlweise um den ap und die steckverbindungen oder den kleinen bruder wickeln und gut ist. oder alternativ (wenn du zu geizig bist), dem kleinen bruder mit schlaegen drohen *g*
 
Hallo Soon5,

Soon5 schrieb:
Am Rande, ich hab mal ne andere Frage. besteht die möglichkeit einen Shell Befehl x Minuten nach dem booten auszuführen (Also nach dem booten z.B. 10 min Warten dann Shell befehl ausführen). Der Befehl ist einmalig, muss also nur einmal ausgeführt werden.

Code:
man at
ist Dein Freund :)

Hintergrund. Ich hab eine externe Festplatte am laufen. Wenn ich die gleich beim booten über fstab mounte geht es nicht (bekomme Fehler, rechner stürzt ab). Wenn ich sie so 3 min nach dem booten manuell mounte gehts ohne Probleme (kein Plan warum, ist aber so).
Soon5
SCSI oder IDE? Falls SCSI, mal Kabel und Terminierung überprüfen.

Viele Grüße

Jürgen
 
Hy,

Wie genau funktioniert das mit dem "man at"? Hab das net ganz verstanden

Die Festplatte ist IDE und wird über ein USB Gehäuse angeschlossen.

MfG

Soon5
 
Zuletzt bearbeitet:
Unter FreeBSD gibt es drei Systeme, welche zeitgesteuert Befehle abarbeiten:
crontab, at und periodic. Alle drei werden von cron gestartet. Cron startet die Befehle gemäss /etc/crontab:
Code:
# /etc/crontab - root's crontab for FreeBSD
#
# $FreeBSD: src/etc/crontab,v 1.32 2002/11/22 16:13:39 tom Exp $
#
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
HOME=/var/log
#
#minute hour mday month wday who command
#
*/5 * * * * root /usr/libexec/atrun
#
# Save some entropy so that /dev/random can re-seed on boot.
*/11 * * * * operator /usr/libexec/save-entropy
#
# Rotate log files every hour, if necessary.
0 * * * * root newsyslog
#
# Perform daily/weekly/monthly maintenance.
#1 3 * * * root periodic daily
#15 4 * * 6 root periodic weekly
#30 5 1 * * root periodic monthly
#
# Adjust the time zone if the CMOS clock keeps local time, as opposed to
# UTC time.  See adjkerntz(8) for details.
1,31 0-5 * * * root adjkerntz -a
at
---
Die Zeile mit atrun startet at alle 5 Minuten. Alle 5 Minuten wird geprüft, ob kein Job in der at-Warteschlange liegt. Ein Beispiel:

# at -f <Pfad zum Shellskript> + 10 minutes

Siehe auch:

# man at

periodic
---------
Die Zeilen mit periodic starten die entsprechenden Shellskripte im Verzeichnis /etc/periodic. Die Ausgaben der Shellskripte werden per E-Mail an root gesendet. Siehe auch:

#man periodic

Ein Beispiel findest Du unter:
http://wiki.bsdforen.de/tiki-index.php?page=Ports+und+Programme+aktualisieren

crontab
--------
Mit # crontab -e kannst Du für jeden Benutzer zum gewünschten Zeitpunkt Befehle ausführen lassen. Siehe auch:

# man crontab
# man cron
http://www.freebsd.ch/doc/de_DE.ISO8859-1/books/handbook/configtuning-cron.html
http://www.bsdforen.de/showthread.php?t=6650
 
Zuletzt bearbeitet:
Hy,

Ich werd noch wahnsinnig. Entweder bin ich zu blöd die richtigen Begriffe bei google einzugeben, oder ich habs übersehen.

Es ist im Endefekt ganz einfach. Ich will ein sh Script beim Booten einmal starten. Direkt ohne verzögerung. In welche Datei muss ich das eintragen.

Danke schonmal, und noch einen guten Rutsch.

MfG

Soon5
 
Hallo Soon5,

dieses Skript stellst Du in /usr/local/etc/rc.d und vergiß nicht, die x-permission zu setzen :D

Viele Grüße

Jürgen
 
Zurück
Oben