bash If ... or ... then ...

  • Hi
    hab da ein kleines Problem mit einer IF THEN Abfrage
    Eigentlicher habe ich eher ein Problem mit dem OR
    Kann mir jemand sagen warum das nicht funktioniert bzw. wie es richtig funktiiniert?

    Danke

  • nimm || statt or



    Hallo,

    die Disjunktion ist in der Bash &&.

    Code
    if [ ... ] && [ ... ]; then


    es geht um "oder" nicht.. "und"

    in brackets kannst du das || allerdings nicht nutzen..
    da wäre zum beispiel folgendes passender

    Code
    if [ 'ping -q -c 1 $IP1' -o 'ping -q -c 1 $IP2' ]

    was bei der ganzen sache allerdings nicht bedacht wird, ist, dass der rückgabewert von ping hier falsch angenommen wird..

    Einmal editiert, zuletzt von demlak (23. November 2014 um 21:25)

  • Das wird so aber trotzdem nicht gehen da ping in der Form nicht ausgeführt wird.
    Das funktioniert nicht:

    Code
    'ping -q -c 1 192.168.0.103'


    Erst das funktioniert:
    Entweder

    Code
    `ping -q -c 1 192.168.0.103`


    oder

    Code
    $(ping -q -c 1 192.168.0.103)

    (meine bevorzugte Schreibweise)

    Desweiteren brauch man hier eigentlich keine doppelte Klammer ( [[ und ]] )

    Und zu guter letzt ist der Punkt hier: /home/pi/raspberry-remote/./send
    überflüssig da der vollständige Pfad angegeben wird

    Wobei ein hab ich noch: Wenn die Einrückungen richtig wären, könnte man den Code auch besser lesen/entziffern/verstehen

  • die doppeklten klammern gehen auch nur in bash.. aber nich in sh.. was je nach verwendungszweck auch probleme bringen kann...
    und wie gesagt.. das mit den exitcodes ist so eine sache,... ich würd folgendermaßen das ganze machen:

    Code
    if [ `ping -c 1 $IP1 >> /dev/null;echo $?` -eq 0 ] || [ `ping -c 1 $IP2 >> /dev/null;echo $?` -eq 0 ]

    ping produziert mehrere exitcodes.. gesucht wird aber nach "0".. was für "host reachable" steht..

  • aber es funktioniert =)
    ich bin kein coder.. aber da ich neugierig war, hab ich grad viel gegoogled und ausprobiert.. und das war das einzige was mich ans ziel führte =)

    hier noch die andere schreibweise, welche meigrafd erwähnte.. (find ich im übrigen auch übersichtlicher)

    Code
    if [ $(ping -c 1 $IP1 >> /dev/null;echo $?) -eq 0 ] || [ $(ping -c 1 $IP2 >> /dev/null;echo $?) -eq 0 ]
  • Hi,

    Hier könnte man auch einfach die Klammern komplett weglassen. :)

    Code
    if ping -c1 192.168.0.103 || ping -c1 192.168.0.104

    Um das ganze etwas übersichtlicher zu machen würde ich aber dennoch Klammern setzten und die ganze Ausgabe (dieser Kommandogruppe) ins /dev/null umleiten.

    Code
    if (ping -c1 192.168.0.103 || ping -c1 192.168.0.104) > /dev/null 2>&1

    Und dann, wenn wirklich nötig einfach im nächsten Schritt den exit status auswerten. (Edit: Dazu müsste man dann aber doch den Exit Status der einzelnen ping Befehlen in einer Variable zwischenspeichern und dann einzeln auswerten. Das wäre mir viel zu aufwändig und ist hier auch nicht nötig.

    Bist du dir auch sicher dass du ein ODER brauchst, und nicht doch ein UND? :)
    Zur Erinnerung:
    ODER bedeutet dass einer der beiden Hosts erreichbar sein muss damit der Ping erfolgreich ist, welcher das ist, ist dabei egal.
    UND würde bedeuten dass beide erreichbar sein müssen.
    )

    DON'T PANIC!

    Einmal editiert, zuletzt von joh.raspi (24. November 2014 um 05:39)

  • Ersteinmal vielen Dank für die zahlreichen Antworten. Damit kann ich arbeiten :)

    Die Programmiersprache ist mir leider völlig Fremd. Bin mehr auf dem .Net Sektor Zuhause, was zwar Ähnlichkeiten aufweist aber eben auch nicht wirklich vergleichbar ist.
    Daher taste ich mich jetzt mal immer Stück für Stück voran ...

    Ich weiß das es nicht sauber programmiert ist, aber wie schrieb einer bereits, es funktioniert :)
    Ich werde das Programm letztendlich auch anders schreiben, boolscher Wert für die IP's
    Sudo nur ausführen wenn IP= True und so weiter

    Hintergrund des ganzen ist, dass wir nicht im dunklen Hausflur stehen wollen wenn wir Nachhause kommen.
    Wenn Handy da dann ...
    - Licht für drei Minuten ein -> dann aus
    Warte bis der Status des Handy sich ändert ... uswusf

  • Ich sage schon mal sorry dafür, muss nicht schön sein sondern soll "nur" funktionieren =)
    Kann es auch gerade nicht testen weil ich auf Arbeit nicht die Möglichkeit dazu habe.

    Könnte das so funktionieren?

    Einmal editiert, zuletzt von JT179 (24. November 2014 um 11:17)

  • tom.angelripper hat es bereits angesprochen wie es eigentlich aussehen sollte, denn ein ping ansich reicht nicht, egal wie der Exitcode aussieht... Wichtig ist ob auch ein Ping zurück kommt ;)

    Zu diese Thema gabs hier aber schon mal irgendwo einen Thread mit einer ziemlich ähnlichen Idee (etwas einschalten wenn das Handy Abends im WLAN (oder wars später via Bluetooth?) erreichbar ist.. Leider weiß ich nicht mehr wie der Thread hieß, hab mittlerweile in zu vielen geholfen um mir alle zu merken :(

    Zu deinem Script @ JT179: Du solltest dir mal eine übersichtlichere Schreibweise angewöhnen... Entweder nutzt man TABs zum Einrücken, oder zum Beispiel 2 bzw 4 Leerzeichen... Auch so viele Leerzeilen zerren das Script nur unnötig auseinander und machts unübersichtlich - gerade für uns Helfer is das echt Hardcore

    Nur mal als Vergleich, Dein Script so wie Du es hier gepostet hast:

    Spoiler anzeigen

    Und hier wie es eigentlich aussehen sollte:

    Spoiler anzeigen


    Siehst du den Krassen Unterschied?
    Man kann bei der unteren Schreibweise viel besser und eindeutiger erkennen welcher Code zu welchem Abschnitt bzw if Schleife gehört

    Eigentlich sollte es auch egal sein ob du zuvor eine andere Programmiersprache gewohnt bist - eine gewisse Übersichtlichkeit sollte überall vorhanden und im eigenen Interesse sein ;)


    Noch mal zurück zur Funktionsweise des Scripts:

    • Nur etwas anzupingen reicht nicht, man sollte auch prüfen ob ein Ping zurück kam
    • Es wäre zu empfehlen auch einen Timeout im Ping-Befehl zu verwenden damit dieser nicht 10 Minuten sich quasi aufhängenderweise totläuft..
    • Was ist wenn das ein mal durch gelaufen ist, was hindert es daran noch weitere male das Licht einzuschalten usw? Weil das Handy wird höchst wahrscheinlich auch weiterhin noch Pingbar sein oder nicht? Dein Handy ist zwar tagsüber nicht pingbar aber sobald du Abends nachhause kommst ist es die ganze Zeit pingbar... Oder was ist am nächsten Tag? Startest du das Script dann jeden Abend neu? ;)
      Du prüfst auch nicht vor dem " if $online; " ob beim 2.Durchlauf LWO an war, diese If Schleife wird dann immer und immer wieder ausgeführt.
    • Ist das Handy auch im WLAN wenn es im Standby ist? Wenn nein wäre es dann auch nicht pingbar - das war das Problem im anderen Thread weswegen der auf Bluetooth gewechselt hat...

    Zu 1. und 2.:
    Eine entsprechender Befehl könnte wie folgt aussehen:

    Code
    echo $(ping -q -W1 -c1 $IP | grep '1 received')

    In einer if-Schleife also:

    Code
    if [ ! -z "$(ping -q -W1 -c1 $IP | grep '1 received')" ]; then

    oder:

    Code
    if [ -n "$(ping -q -W1 -c1 $IP | grep '1 received')" ]; then

    ist beides das selbe. -z prüft auf "leer". " ! " steht für NICHT. Kombiniert: wenn nicht leer. -n macht das selbe: wenn nicht leer .. Wenn also die Rückgabe des Befehls nicht leer ist trifft die if-Schleife zu und "then" wird ausgeführt

    Zu 3.:
    Ausserdem würde ich die Uhrzeit prüfen sowie speichern ob Abends auf das Handy bereits reagiert wurde.. Dafür bietet sich auch eine SQLite Datenbankdatei an damit der Status nach einem neustart des Scripts/PIs nicht verloren ist.

    Zu 4.:
    Überprüf das mal obs Handy im Standby über WLAN auch noch Pingbar ist.

  • Hi,

    meigrafd, Du machst dir aber auch immer wieder eine Mühe. :thumbs1:
    *An dieser Stelle einfach mal kurz ein :danke_ATDE: zuwerf*

    ----------
    Irgendwie stehe ich aber wohl gerade etwas auf dem Schlauch. :s
    Wieso muss ich den output parsen um zu wissen dass der Ping erfolgreich ist?
    Die einzige Möglichkeit dass Ping den Exit code 0 zurückgibt ist doch wenn der Ping auch erfolgreich ist, also ein Packet erfolgreich zurückgekommen ist.

    Grüße,
    Joh

    DON'T PANIC!

    Einmal editiert, zuletzt von joh.raspi (24. November 2014 um 18:51)

  • Zitat


    Noch mal zurück zur Funktionsweise des Scripts:

    • Nur etwas anzupingen reicht nicht, man sollte auch prüfen ob ein Ping zurück kam

    • Wenn der Ping erfolgreich war kam doch etwas zurück...

      Zitat
    • Zitat

      Es wäre zu empfehlen auch einen Timeout im Ping-Befehl zu verwenden damit dieser nicht 10 Minuten sich quasi aufhängenderweise totläuft..


      Passiert das?

      Zitat
    • Zitat

      Was ist wenn das ein mal durch gelaufen ist, was hindert es daran noch weitere male das Licht einzuschalten usw? Weil das Handy wird höchst wahrscheinlich auch weiterhin noch Pingbar sein oder nicht? Dein Handy ist zwar tagsüber nicht pingbar aber sobald du Abends nachhause kommst ist es die ganze Zeit pingbar... Oder was ist am nächsten Tag? Startest du das Script dann jeden Abend neu? ;)
      Du prüfst auch nicht vor dem " if $online; " ob beim 2.Durchlauf LWO an war, diese If Schleife wird dann immer und immer wieder ausgeführt.


      Darum die boolsche Variable LWO, dort wird wird festgestellt ob sich der onlinezustand geändert hat, sprich das Handy mal nicht im WLan war, quasi das Haus verlassen hat.

      Zitat
    • Zitat

      Ist das Handy auch im WLAN wenn es im Standby ist? Wenn nein wäre es dann auch nicht pingbar - das war das Problem im anderen Thread weswegen der auf Bluetooth gewechselt hat...

    Zitat


    Hab ich gelesen, Bluetooth kommt für mich aber nicht in Frage da nicht immer eingeschaltet.

    Zitat


    Zu 1. und 2.:
    Eine entsprechender Befehl könnte wie folgt aussehen:

    Code
    echo $(ping -q -W1 -c1 $IP | grep '1 received')

    In einer if-Schleife also:

    Code
    if [ ! -z "$(ping -q -W1 -c1 $IP | grep '1 received')" ]; then

    oder:

    Code
    if [ -n "$(ping -q -W1 -c1 $IP | grep '1 received')" ]; then

    ist beides das selbe. -z prüft auf "leer". " ! " steht für NICHT. Kombiniert: wenn nicht leer. -n macht das selbe: wenn nicht leer .. Wenn also die Rückgabe des Befehls nicht leer ist trifft die if-Schleife zu und "then" wird ausgeführt

    Schau ich mir mal an

    Zitat


    Zu 3.:
    Ausserdem würde ich die Uhrzeit prüfen sowie speichern ob Abends auf das Handy bereits reagiert wurde.. Dafür bietet sich auch eine SQLite Datenbankdatei an damit der Status nach einem neustart des Scripts/PIs nicht verloren ist.


    Ist mir zu aufwändig, ist nicht weiter schlimm wenn die Lampe mal 3 Minuten bei Helligkeit leuchtet.

    Zitat


    Zu 4.:
    Überprüf das mal obs Handy im Standby über WLAN auch noch Pingbar ist.

    Ist Andoid, also ja ist es

    Ich sage erst einmal, vielen Dank
    Das ist jetzt so viel Input das muss ich erst einmal selektieren :)
    Werde aber auf jeden Fall das Resultat posten

    Habt vielen Dank
    LG
    Timo

Jetzt mitmachen!

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