bash>> if then Verständnisproblem

sbr2d2

Registered User
Hallo,
ich versuche gerade ein kleines Abfragescript zum laufen zu bekommen und weiß gerade nicht weiter. Vorweg mal der Part der nicht läuft.
Code:
if [[ $job1 -le 15 ]] ; then
echo "hier koennte was ausgefuehrt werden"
else
echo "das andere"

fi
Um es kurz zu erklären, die Variable job1 ist eine Zahl zwischen 0-45. Ist die Zahl kleiner als 15 soll das erste Echo zum tragen kommen, ist sie größer wie 15 dann das zweite. Aber egal was für einen Wert job1 bekommt, es wird immer das erste Echo ausgeworfen. Für Tipps bin ich wie immer Dankbar.
Gruß s.b.
 

sbr2d2

Registered User
Dann frage ich mich was hier nicht läuft und warum. Mal etwas erweitert dargestellt.
Code:
job2=$(mysql -u root -e "use testdb2; SELECT SUM(Limit2.Dauer) AS Dauer2Jobs
FROM (SELECT jobstat.Dauer FROM jobstatistik AS jobstat ORDER BY ID DESC Limit 2) AS Limit2;" | tail -n 1)

echo "$job2"

    if [ $job2 == 0.00 ] ; then
    service mysql restart

fi

fi
    job1=$ echo ${job2%%.*}
    echo "$job1"


    if [[ $job1 -le 15 ]] ; then
    echo "hier koennte was ausgefuehrt werden"
    else
    echo "das andere"

fi
Die erste Variable wird aus einer Datenbank generiert und dann Verglichen. Ist der Wert 0.00 wird der sql Server neu gestartet. Ist er größer wie 0.00 wird die Variable um alles nach dem . gekürzt und in eine neue Variable gepackt. Die werd dann von der nächsten if/then Abfrage benutzt. Dabei lass ich zur Kontrolle noch die Variablen einmal auswerfen bevor sie verarbeitet werden. Aber wie man bei meinem Screen sehen kann, macht es nicht so wie es soll.
Screenshot_2.jpg

Also das erste funktioniert aber leider die zweite Abfrage nicht.
 

d4f

Müder Benutzer
Ohne Shellscripting-Spezialist zu sein, würde ich für solche simple Skripte zwecks Portabilität keine Doublebrackets "[[" verwenden da diese nicht POSIX-compliant sind und nur in einigen Shells funktionieren. Dazu dann $job1 und $job2 in den Vergleichen immer in Anführungszeichen setzen; wenn die Variable leer ist kann es sont zu unerwarteten Nebeneffekten kommen da dann schlicht "if [ -le 15 ]" da steht was syntaktisch inkorrekt ist.

Bitte das ganze Script inklusive Shebang Header angeben, bist du überhaupt in einer Bash-Umgebung?

Hier ist wohl ein Copy-Paste Fehler unterlaufen:
Code:
job1=$ echo ${job2%%.*}
Was soll der Schnipsel (korrigiert) erfüllen? Du entfernst aus der Variable gerne alles von hinten aus?
Wenn ich dein Code richtig erkenne hast du ja eh eine Zahl, kannst also direkt Grössenvergleiche ausführen. Höchstens inklusive Sanitycheck auf leeren Wert? In diesem Stil:
Code:
if [ "$job2" == "" ]; then
   echo "Hilfe ich bin leer!"
elif [ "$job2" -eq 0 ]; then
   service mysql restart
elif [ "$job2" -le 15 ]; then
   echo "Hier mal was ausführen bitte =)"
else
   echo "Irgendwas anderes?"
fi
 

nexus

Well-Known Member
Code:
job1=$ echo ${job2%%.*}
Wird hier nicht auch der Variablen eine Zeichenkette zugewiesen? Wenn ja, dann müßte doch der darauf folgende Vergleich mit einem numerischen Wert fehlschlagen...?
Ach man, ich hab schon zu lange keine Shellscripte mehr geschrieben... :confused:
 
Last edited:

sbr2d2

Registered User
Hier dann das ganze Script etwas aufbereitet
Code:
#!/bin/bash
cd /

## Notfalltest Teil1
echo "Test 1 wird gestartet"

## datenbank auslesen und in Variable packen

job4=$(mysql -u root -e "use testdb2; SELECT SUM(Limit4.Dauer) AS Dauer3Jobs
FROM (SELECT jobstat.Dauer FROM jobstatistik AS jobstat ORDER BY ID DESC Limit 4) AS Limit4;" | tail -n 1)

##Variable testen und verarbeiten
echo "$job4"

if [ $job4 == 0.00 ] ; then
/root/bin/./notfall.sh > /dev/null
else

## Notfalltest Teil2
echo "Test 2 wird gestartet"

## datenbank auslesen und in Variable packen

job2=$(mysql -u root -e "use testdb2; SELECT SUM(Limit2.Dauer) AS Dauer2Jobs
FROM (SELECT jobstat.Dauer FROM jobstatistik AS jobstat ORDER BY ID DESC Limit 2) AS Limit2;" | tail -n 1)

##Variable testen und verarbeiten

echo "$job2"

    if [ $job2 == 0.00 ] ; then
    service mysql restart
fi

fi
##Systemtest zum starten oder geschlossen halten
##Variable aus Teil2 kürzen und in neue Variable packen und testen
    job1=$ echo ${job2%%.*}
    echo "$job1"

    if [[ $job1 -le 15 ]] ; then
    echo "hier koennte was ausgefuehrt werden"
    else
    echo "das andere"
fi
Die Kürzung in der Variable Job1 ist nötig, weil das Script sonst mit Fehler abbricht. Am Ende kommt dann ein Zahl ohne .45 oder sonst was raus. Zur Erklärung von dem ganzen Script. Es dient als vorläufige Maßnahme bis die Anwendung davor Fehlerfrei läuft. Es werden aus einer Datenbank einmal die letzten 4 Eintrage ausgelesen und der Durchschnitt errechnet. Sollte da 0.00 bei raus kommen, werden Notfallmaßnahmen ergriffen.
Der zweite Test ist eigentlich dem ersten vorgeschaltet, testet die letzten 2 Einträge und bei Ergebnis 0.00 wird der sql Server neu gestartet was meistens hilft. Erst wenn das nicht mehr hilft, greift Test1. Der letzte dient nur dazu, bei einem bestimmten Wert das System wieder frei zu geben, und zwar erst wenn der Wert unter 15 fällt.
 

d4f

Müder Benutzer
Danke für die Erläuterung. Bitte die erste Zeile (Shebang) des Skriptes trotzdem angeben. Grund ist dass zB unter Debian /bin/sh NICHT bash ist sondern dash und dash bspw (zumindest in Originalform) nicht das "[[" Doublebracket kennt. Wenn du aber "/bin/bash" benutzt oder bspw unter Redhat-Derivaten arbeitest, dann ist das wieder hinfällig.

Shell-Dialekte können generell kein Float, richtigerweise substituierst du also mit ${job2%%.*} den Punkt und alle nachfolgenden Zeichen mit dem leeren String (aka: abschneiden). Soweit so gut, aber das Konstrukt rundherum ist wohl dein Problem.
Richtig wäre die Zeile schlicht kürzer =)
Code:
job1=${job2%%.*}
#Das hier geht aber auch da shortest-path und longest-path egal sind solange es nur einen Punkt gibt
job1=${job2%.*}
Meine vorherige Empfehlung Variablen generell und insbesondere beim Vergleich in doppelte Anführungszeichen zu packen empfehle ich aber auch weiterhin ;)
 

sbr2d2

Registered User
Ich danke Euch, jetzt macht es wie es soll. Die angegebene Shell sollte richtig sein.
Ein echo $SHELL liefert ein /bin/bash zurück. System ist eine Ubuntu 18. Habe jetzt alle Variablen in doppelte Anführungszeichen gepackt und die Zeile von d4f übernommen. Die funktionierende Version sieht jetzt so aus.

Code:
#!/bin/bash
cd /

## Notfalltest Teil1
echo "Test 1 wird gestartet"

## datenbank auslesen und in Variable packen

job4="$(mysql -u root -e "use testdb2; SELECT SUM(Limit4.Dauer) AS Dauer3Jobs
FROM (SELECT jobstat.Dauer FROM jobstatistik AS jobstat ORDER BY ID DESC Limit 4) AS Limit4;" | tail -n 1)"

##Variable testen und verarbeiten
echo "$job4"

if [ $job4 == 0.00 ] ; then
/root/bin/./notfall.sh > /dev/null
else

## Notfalltest Teil2
echo "Test 2 wird gestartet"

## datenbank auslesen und in Variable packen

job2="$(mysql -u root -e "use testdb2; SELECT SUM(Limit2.Dauer) AS Dauer2Jobs
FROM (SELECT jobstat.Dauer FROM jobstatistik AS jobstat ORDER BY ID DESC Limit 2) AS Limit2;" | tail -n 1)"

##Variable testen und verarbeiten

echo "$job2"

    if [ $job2 == 0.00 ] ; then
    service mysql restart
fi

fi
##Systemtest zum starten oder geschlossen halten
##Variable aus Teil2 kürzen und in neue Variable packen
    job1="${job2%%.*}"
##alt    job1=$ echo ${job2%%.*}
    echo "$job1"

    if [[ $job1 -le 15 ]] ; then
    echo "hier koennte was ausgefuehrt werden"
    else
    echo "das andere"
fi
Screenshot_1.jpg
 

sbr2d2

Registered User
Hier die Ausgabe.
Code:
bash -x ./jobtest.sh
+ cd /
+ echo 'Test 1 wird gestartet'
Test 1 wird gestartet
++ mysql -u root -e 'use testdb2; SELECT SUM(Limit4.Dauer) AS Dauer3Jobs
FROM (SELECT jobstat.Dauer FROM jobstatistik AS jobstat ORDER BY ID DESC Limit 4) AS Limit4;'
++ tail -n 1
+ job4=16.52
+ echo 16.52
16.52
+ '[' 16.52 == 0.00 ']'
+ echo 'Test 2 wird gestartet'
Test 2 wird gestartet
++ mysql -u root -e 'use testdb2; SELECT SUM(Limit2.Dauer) AS Dauer2Jobs
FROM (SELECT jobstat.Dauer FROM jobstatistik AS jobstat ORDER BY ID DESC Limit 2) AS Limit2;'
++ tail -n 1
+ job2=8.70
+ echo 8.70
8.70
+ '[' 8.70 == 0.00 ']'
+ job1=8
+ echo 8
8
+ [[ 8 -le 15 ]]
+ echo 'hier koennte was ausgefuehrt werden'
hier koennte was ausgefuehrt werden
 

Firewire2002

Registered User
Nun ja in dem Scriptlauf war es ja offensichtlich völlig korrekt. 8 ist kleiner als 15. Bedingung greift, Inhalt des If-Blocks wird ausgeführt.
Nun also bitte die Ausgabe von bash -x mit dem vermeintlich fehlerhaften Resultat. ;)
 

sbr2d2

Registered User
Es läuft ja jetzt wie es soll. Habe ich im Beitrag Nr8 schon geschrieben. Um den anderen Fall passieren zu lassen, muss ich an in der DB dann die Werte manuell ändern solange es läuft wie es soll. Aber das kann ich morgen gerne machen.
 
Top