2 Faktoren abfragen in bash script

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hey Ho,

    Ich habe ein kleines Programm, welches einen Schalter überwacht und bei Betätigung des Schalters eine PHP script aufruft und in eine log dabei schreibt.

    Nun soll das ganze so erweitert werden, dass bevor das PHP script aufgerufen wird erst die Log dabei abgefragt wird, sollte dort bereits Einsatz stehen, soll das PHP Script nicht ein weiteres mal aufgerufen werden

    Mein Script sieht im moment so aus:


    f [ "$result" = "0" ]; then hier sollen sogeschen 2 Faktoren abgefragt werden, nur wenn $result" ="0" und in der log.txt "kein Einsatz" steht, soll in die Log.txt Einsatz geschrieben werden und das Script aufgerufen werden.

    das gleiche auch umgekehrt bei der 2ten abfrage.


    ich hoffe ihr könnt mir helfen.

    Gruß, C4

  • Hallo,

    Die Abfrage ist nicht ganz richtig.

    result="$( gpio read 2 )" soll wahrscheinlich eine zahl zum string konvertieren.
    Wäre nicht unbedingt nötig

    Code
    result=$( gpio read 2 )
    
    
    if [ $result -eq 0 ]; then

    wenn
    result="$( gpio read 2 )"

    Code
    if [ $result == "0" ]; then

    Weiß nicht genau ob ich deine Frage richtig verstanden habe.
    Ich denke du meinst.

    Code
    if [ $result == "0" ]; then
    ...
    elif[ $result == "1" ]; then
    ...
    fi

    Oder vielleicht meinst du ja eine boolsche Verknüpfung

    Code
    if [ $result == "0" -a $(grep -c "kein Einsatz" datei) -eq 0 ]; then
    ...


    Gruß
    Klaus

    Einmal editiert, zuletzt von klaus_harrer (5. Mai 2016 um 15:51)

  • vom Prinzip soll wenn der schalter gedrückt ist also die Ausgabe von gpio read 2 eine 0 ist und in der log.txt steht "kein Einsatz" in die Log.txt Einsatz geschrieben werden und der link aufgerufen.
    solange "Einsatz" in der Log.txt steht soll der link nicht ein weiteres mal aufgerufen werden, auch wenn die Ausgabe von gpio read 2 immer noch eine 0 ist.

    hoffe das ist nun verständlich.

  • Hallo

    Dann müsste man die Verknüpfung nehmen.

    Code
    if [ $result == "0" -a $(grep -c "kein Einsatz" log.txt) -gt 0 ]; then
    ...
    fi

    Muss halt noch ein wenig angepasst werden.

  • Ich würde in bash immer die neuere Art eine Bedingung abzufragen benutzen. Die ist mächtiger und entspricht mehr dem was man von einer höheren Programmiersprache kennt. Du kannst && als und Verküpfung benutzen für Bedingungen. Die Art und Weise wie Du Dir in der log.txt merkst ob ein Einsatz ist oder nicht finde ich etwas umständlich. Ich würde die Datei einsatz.status erzeugen wenn ein Einsatz ist und sie löschen wenn kein Einsatz ist und dann mit if [[ -f einsatz.status ]] im Script jeweils testen ob Einsatz ist oder nicht. Aber der folgende Code funktioniert auch mit 'Einsatz' und 'kein Einsatz'.

    [code=php]
    #!/bin/bash

    echo "kein Einsatz" > log.txt
    result=0

    if [[ $result == "0" && $(grep "kein Einsatz" log.txt) ]]; then
    echo "Result ist 0 und 'kein Einsatz' gefunden"
    else
    echo "Result ist nicht 0 oder nicht 'kein Einsatz' gefunden"
    fi

    echo "Einsatz" > log.txt
    result=0

    if [[ $result == "0" && $(grep -v "^Einsatz" log.txt) ]]; then
    echo "Result ist 0 und kein 'Einsatz' gefunden"
    else
    echo "Result ist nicht 0 oder 'Einsatz' gefunden"
    fi

    echo "kein Einsatz" > log.txt
    result=0

    if [[ $result == "0" && $(grep -v "^Einsatz" log.txt) ]]; then
    echo "Result ist 0 und kein 'Einsatz' gefunden"
    else
    echo "Result ist nicht 0 oder 'Einsatz' gefunden"
    fi
    [/php]

  • danke erst mal für die schnellen Antworten, ich versuche jetzt mal, mir aus den Vorschlägen hier was zusammen zu basteln.
    Im Endeffekt soll ja nur verhindert werden, dass wenn der Schalter noch geschlossen ist, das PHP script endlos oft aufgerufen wird.

    die Log.txt soll später noch anders verwendet werden, in ihr soll später auch die Uhrzeit gespeichert werden, welche mittels PHP script abgefragt wird.

  • wie würde das denn gehen?

    wenn Schalter geschlossen die Datei erzeugen, URL aufrufen,
    dann abfragen, wenn dabei besteht, URL kein weiteres mal aufrufen,
    Wenn schalter dann wieder geöffnet, URL2 einmal aufrufen und dann wieder warten, bis schalter geschlossen?

  • Hi,
    ich hab' das jetzt nur mal so als Idee eingekippt ohne mir das alles jetzt genau durchzulesen.
    Ich denke, das Handling wäre äquivalent zu Deinen Einträgen "Einsatz" / "kein Einsatz" ...
    Also statt

    Code
    echo "einsatz" > log.txt


    einen create auf z.B. /var/log/Einsatz.LCK
    und statt

    Code
    echo "kein einsatz" > log.txt


    einen delete von z.B. /var/log/Einsatz.LCK

    Ist die Datei vorhanden, ist ein Einsatz aktiv, wenn nicht halt nicht ;) ...
    Die Einträge in Deine Logdatei kannst Du ja trotzdem machen, weil Du diese ja scheinbar noch anderweitig verwenden willst.
    Du brauchst halt nicht mehr im File suchen sondern kannst Dich nach Herzenslust mit der Logdatei austoben, weil Du ja nur auf die Existenz der .LCK Datei reagierst.

    Müsste doch einfacher sein, oder?

    cu,
    -ds-

  • Na ... da siehste mal ...
    Wie sagt man so schön "Zwei Deppen ein Gedanke" ...
    Ich sag' ja ... ich hab mir das gar nicht so genau durchgelesen. Das war mein erster, spontaner Gedanke. Aber jetzt, wo Du's sagst ;) ...
    Naja ... Doppelt genäht hält besser ...

    cu,
    -ds-

  • Ich habe es mir nun mal so zusammen getippt, das einschalten klappt auch einwandfrei, wenn der Schalter geschlossen wird, wird einmal die URL aufgerufen, jedoch wenn der Schalter geöffnet ist, wird die URL im 5 sec Takt aufgerufen was zu ein paar Problemen führt....

    So sieht mein aktueller code aus:

    Kann ja eigentlich nicht viel sein, oder?

  • Hi,


    Ich habe es mir nun mal so zusammen getippt, das einschalten klappt auch


    naja ... passt doch. Wie sagt man "Wer zoid schaffd o" ...
    Mach das so, wenn Du meinst. Will Dich ja hier niemand zu was zwingen ;) ...


    ...
    if [[ "$result" = "0" && $(grep "kein einsatz" log.txt) ]] ; then
    ...
    if [[ "$result" = "1" && $(grep "einsatz" log.txt) ]] ; then
    ...


    bist Du sicher, dass das so stimmt?
    cu,
    -ds-

  • Du hast ein kleines Zeichen übersehen ;)

    Du hast geschrieben
    $(grep "einsatz" log.txt)

    Ich habe geschrieben
    $(grep "^einsatz" log.txt) :shy:

    Das ist wichtig.

    Hintergrund: Der grep sucht in der Datei ob der Text 'einsatz' irgendwo vorkommt. Dieses ist immer wahr denn sowohl 'einsatz' als auch 'kein einsatz' enthält ja den Text 'einsatz'.

    Mit '^einsatz' suchst Du nach dem Text 'einsatz' am Anfang des Textes. D.h. 'kein einsatz' wird dann nicht gefunden.

  • Um das noch mal festzuhalten:
    - An einen GPIO ist ein Schalter angeschlossen.
    - Wird der Schalter betätigt soll eine URL aufgerufen werden.
    - Da sich das Script permanent im Kreis dreht soll die URL nur ein mal aufgerufen werden...
    -- GPIO = 1 = URL zum Einschalten aufrufen, beim nächsten Durchlauf nicht erneut URL aufrufen. GPIO = 0 = URL zum Ausschalten aufrufen, beim nächsten Durchlauf nicht erneut URL aufrufen.

    Ob bei umlegen eines Schalters der GPIO eine 1 ausgibt hängt davon ab wie dieser Taster angeschlossen ist. Stichwort: Pull Up or Pull Down

    Für mich sieht es jetzt so aus als würde nur wichtig sein das der vorherige Schaltzustand beim nächsten Durchlauf der while bekannt sein muss damit der selbe Status nicht noch mal eine Aktion auslöst? Dann bedarf es eigentlich keiner (log)Datei

    Als allgemeiner Tipp:
    Auch wenn Einrückungen für Bash nicht wichtig sind, erhöhen sie die Ordnung und Lesbarkeit des Scripts.
    Das Konsolen Programm "gpio" ist langsamer als mit den sysfs Dateien zu arbeiten.
    Dein Shebang soll "sh" verwenden, allerdings ist sh älter und kann nicht so viel wie "bash". Man sollte wenn möglich immer bash nutzen.
    Immer vollständige Pfade zu wichtigen Dateien verwenden.
    Bei if Abfragen sollte man immer mit Quotes arbeiten.

    Mein Vorschlag:
    [code=php]
    #!/bin/bash

    # BCM GPIO Number
    GPIOpin=27

    ## init GPIOpin
    if [ ! -f /sys/class/gpio/gpio${GPIOpin}/value ]; then
    echo $GPIOpin > /sys/class/gpio/export
    echo in > /sys/class/gpio/gpio${GPIOpin}/direction
    fi

    previous_state=$(</sys/class/gpio/gpio${GPIOpin}/value)

    while :; do
    ## get current state
    GPIOstate=$(</sys/class/gpio/gpio${GPIOpin}/value)

    if [ "$GPIOstate" -ne "$previous_state" ]; then
    echo -e "GPIO $GPIOpin: $GPIOstate \t| previous_state: $previous_state"
    if [ "$GPIOstate" = "0" ]; then
    curl "192.168.178.101/GPIO/short/GPIO_short.php?Befehl=r1ein"
    elif [ "$GPIOstate" = "1" ]; then
    curl "192.168.178.101/GPIO/short/GPIO_short.php?Befehl=r1aus"
    fi
    fi
    previous_state=$GPIOstate
    sleep 0.5
    done
    [/php]

    Was das macht ist relativ einfach:
    - Wird das Script ausgeführt wird geprüft ob der GPIO bereits initialisiert wurde und nur wenn das _nicht_ der Fall ist wird dieser initialisiert...
    - Wird das Script ausgeführt wird der aktuelle Status des GPIOs in $previous_state hinterlegt. Wenn der GPIO HIGH ist also eine 1.
    - Die Schleife wird gestartet.
    - Am Anfang der Schleife wird der aktuelle GPIO Status ausgelesen.
    - Ist der GPIO status nicht identisch mit dem vorherigen/alten Status wird eine echo Zeile ausgegeben und je nach GPIO Status die entsprechende URL aufgerufen.
    - Aktueller GPIO Status wird für den nächsten Durchlauf in $previous_state hinterlegt.

    Beispiel zur Schleife in Kurzform:
    $GPIOstate = 1 ; $previous_state = 0
    echo wird ausgegeben da der Vergleich "not equal" zutrifft.
    Wenn $GPIOstate = 0 dann mach Befehl=r1ein aus .... Wenn $GPIOstate = 1 dann mach Befehl=r1aus


  • naja ... passt doch. Wie sagt man "Wer zoid schaffd o" ...
    Mach das so, wenn Du meinst. Will Dich ja hier niemand zu was zwingen ;) ...

    Naja, das ganze soll spätestens am Samstag morgen um 11 Uhr beim nächsten Probe Alarm laufen, demnach bin ich froh, es auf diesem einfachen Wege erst mal zum laufen zu bekommen.
    danach habe ich einen Monat Zeit, mich noch mal genauer mit der Programmierung zu befassen :)

    Meine log.txt wird gleichzeitig in eine PHP Datei eingebunden, welche auf einer Webseite den Status ausgibt.

    Wenn ich bald mal Zeit habe, werde ich hier auch mal mein komplettes Projekt vorstellen, vielleicht ist dann auch übersichtlicher, wofür ich die log.txt brauche, diese nutze ich derzeit als einfachsten Weg, dass mehrere PIs über den Status bescheid wissen und entsprechend reagieren können.


    framp
    Danke, was so ein kleines Zeichen doch ausmacht, jetzt klappt alles wie es soll :)

    Danke an alle anderen, die mich hier mit ihren Ideen unterstütz haben :danke_ATDE:

  • Hey Ho, ich hätte noch mal eine Frage, zu meinem Inzwischen so wie ich es gerne hätte laufenden Script.

    Und zwar möchte ich gerne die Aktuelle Uhrzeit mit einbinden, Hintergrund ist, dass ich die Uhrzeit gerne mit in die Log dabei schreiben würde und außerdem noch abhängig von der Uhrzeit eine weitere URL aufrufen lassen möchte.

    Gedanke ist, dass nach dem ersten sleep von 5 sec der Befehl r1ein nur gesendet wird, wenn es bereits nach 20 und vor 06 Uhr ist, außerdem soll die aktuelle Uhrzeit in die log.txt hinter das wort Einsatz beschrieb en werden.

    Ich denke, das dürfte eigentlich nicht so schwer sein, aber meine Programmierkenntnisse halten sich echt in grenzen...

    Danke, Gruß,
    C4

  • Bei date gibt es ein Format mit dem man Teile aus dem Dateum extrahieren kann (Siehe dazu man date). Du kannst also z.B. die Stunde mit

    Code
    date +%H

    erhalten.

    Dann noch ein wenig Vergleichen gegen die gewuenschte Uhrzeit ;) Anbei mal ein kleines Beispiel:

    [code=php]
    #!/bin/bash

    hour=$(date +%H)

    echo "Es ist $hour Uhr"

    if (( $hour >= 20 )); then
    echo "Es ist nach Acht"
    fi

    if (( $hour < 6 )); then
    echo "Es ist vor Sechs"
    fi

    [/php]

    Die Abfragen kann man dann natürlich noch zusammenfasse wie z.B. :
    [code=php]
    if (( $hour >= 19 && $hour < 20)); then
    echo "Es ist wenigstens 7 Uhr und noch nicht 8 Uhr"
    fi
    [/php]
    Du solltest Dir angewöhnen Deinen Code einzurücken und auch in code oder php Tags zu posten. Damit machst Du es Dir und den Lesern wesentlich einfacher den Code zu lesen:cool:

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!