[fli4l] Hilfe für Skript-Logik

Thomas Grunenberg tho_gru at gmx.de
Di Feb 21 18:18:15 CET 2017


Am 21.02.2017 um 09:52 schrieb K. Dreier:
Hallo Klaus,
> Hallo,
>
> ich brauch mal eure Hilfe, da ich eventuell einen Denkfehler habe.
>
...
>
> # check for devices and set variable according to their status
> exists=$(grep -c -i "100% packet loss" "/data/ping_${device1}.txt")
> # either ping unsuccessful and /device1.online does not exist:
> if [ $exists -gt 0 ] && [ ! -e /var/run/arping.stat/$device1.online ] ;
> then # wenn auch nur eine der beiden Bedingungen _nicht_ zutrifft, ist
> das Gerät online, davon ausgehend, daß "/device1.online" wirklich nur
> existiert, wenn das Gerät verbunden ist
> 	device1_online="false"
> elif [ $exists = 0 ] || [ -e /var/run/arping.stat/$device1.online ] ;
> then
> 	device1_online="true"
> fi

Das was Du da gebaut hast ist "schlecht": Im ersten IF führst Du über 
das Kommando [ den UNIX test Befehl aus (bzw. den entsprechenden Ersatz 
in der Shell, je nachdem wie mächtig die Shell ist). Dann im ELIF führst 
Du test ein zweites Mal aus. Wenn sich die Existenz der Datei genau mit 
der Ausführung des Scripts ändert (das kannst Du leider nicht 
ausschließen), dann wird die Variable device1_online WEDER auf false 
noch auf true gesetzt. Genau aus diesem Grund ist es schlecht, weil 
dieses Verhalten wahrscheinlich selten auftritt... Eventuell liegt hier 
das Problem Deines Scripts.

Im Grunde solltest Du so eine Entscheidung immer wie folgt bauen:
if test ...; then
	command1
else
	command2
fi

Dadurch stellst Du sicher, dass IMMER entweder command1 oder command2 
ausgeführt wird. Es kann NIE passieren, dass keiner vom command1 und 
command2 ausgeführt werden oder beide.
...
> Danke für ein Feedback,
>
> Gruß
> Klaus
>
Allgemeine Bemerkungen:
*)
Nutze das Kommando "set -u" am Anfang Deines Scripts, damit Du auf 
falsch geschriebene Variablennamen hingewiesen wirst.
*)
Wie Peter weiter unten schon angemerkt hat ist ${var} besser/sicherer 
als $var: Damit wird $device1.online zu ${device1}.online oder 
${device1.online}. Wahrscheinlich ist die zweite Schreibweise ungültig, 
weil der . nicht in Variablennamen erlaubt sind. Ich habe mit solchen 
Kleinigkeiten Stunden verbracht, weil ein Script unter einer Shell lief, 
aber unter einer anderen nicht (jede Shell hat so ihre Eigenheiten, was 
die erlaubten Zeichen in Variablennamen sind).
*)
Wenn wie in Deinem Fall ein Test zu wackelig/sensible ist, kannst Du ihn 
mehrfach ausführen und eine Mehrheit bilden. Damit eliminierst Du 
Ausreißer auf Kosten der Laufzeit...
z.B. so:
#!/bin/sh

set -u

file_to_check=/tmp/x1

check_existance() {
         local i
         local check
         local checks
         i=3
         checks=0
         while test "${i}" -gt 0; do
                 check=$(grep -c -i "100% packet loss" "${file_to_check}")
                 checks=$(expr ${checks} + ${check})
                 i=$(expr ${i} - 1)
                 sleep 1
         done
         echo ${checks}
}

exists=$(check_existance)

echo ${exists}

Das ist nur ein Beispiel und muss an Deine Erfordernisse angepasst werden.

Gruß
Thomas



Mehr Informationen über die Mailingliste Fli4L