Bash Script: [: !=: unary operator expected

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo , ich hab heute mein script ausgeführt und habe diesen Fehler bekommen

    Code
    ./tur.sh: line 8: [: !=: unary operator expected

    In das Script sieht so aus:


    Keine Ahnung wieso er meckert.. brauch ich unbedingt ein else? und wenn ja was für eine völlig unnötige Funktion kann ich da einbauen?


    Das Script ist als Tür Email Notification gedacht, das Script verhindert (soll verhindern) das der Mail Ordner vollgespammt wird sobald die Tür offen ist.

  • Color BBcodes funktionieren nicht im CODE tag...

    Setz die Variablen-Abfrage in der if-Schleife mal innerhalb " , jede einzelne also "$neu" und "$alt"

    Was soll $OPEN in der 2.Zeile sein? Die Variable gibt es nicht also ist $neu ebenfalls leer.
    $alt wird zu dem Zeitpunkt ebenfalls nirgends gesetzt also ist auch $vorher leer..
    date=date funktioniert so ebenfalls nicht...

    Die ersten 4 Zeilen musst du also auf jeden Fall überarbeiten.
    home/pi/log.log ist kein absoluter Pfad.
    $alt = $open macht aber ebenso wenig Sinn, nicht nur das sich bash an dem Leerzeichen zwischen variable und Gleichzeichen stören wird, gibts in deinem Script aber auch keine Schleife.

    Scripts, auch Python, werden von oben nach unten abgearbeitet. Was hindert das bash Script daran bei erreichen des Dateiendes sich zu beenden? zZt nichts...

    Also für bash (und die Konsole) musst du erst noch einige Grundlagen lernen :fies:


    PS: Aber wieso machst du das nicht alles im python Script :s

  • Wie meinst du das? also if $alt == 1 then if $neu == 1 nichts?

    Es ist keine Schleife drin aus debugging gründen weil ja sonst alle paar sekunden nen neuer error kommt :D


    Doc h OPEN gibt es das ist der Output aus gpio -g read 4 (also der Status der Tür) ..

    ich musste neu weiter nach unten setzen weil es ja dort noch garkein open gibt oder?


    Ich habe ehrlich gesagt keine Ahnung :denker:

    :danke_ATDE:

  • das done verstehe ich nicht 0 auch so halb aber die ganzen Pluse?

  • Hm ... externes Programm nehme ich jetzt mal an.
    Das hier:


    funktioniert übrigens auf meinem RPi ... gerade mal ausprobiert.
    Da müssen halt evtl. der eine oder andere Komentar raus bzw. das eine oder andere Statement angepasst werden.

    cu,
    -ds-

  • Dann fehlt Dir vermutlich was ...
    Das hier bekomme ich


    wenn ich die letzten beiden Zeilen auskommentiere.

    cu,
    -ds-

  • Hier so sieht mein Script aus :

  • Na da fehlt doch ein 'fi' ...

    cheers,
    -ds-

  • Wie meinst du das? also if $alt == 1 then if $neu == 1 nichts?

    Nein, du solltest die Variablen in " setzen, sie damit umschließen.

    Doc h OPEN gibt es das ist der Output aus gpio -g read 4 (also der Status der Tür) ..

    Nein, nicht zu dem Zeitpunkt wo du es abrufst. Mit $bla möchte man den Wert/Inhalt der Variable 'bla' abrufen/auslesen, aber zu dem Zeitpunkt wo du $OPEN gesetzt hat wurde vorher nichts in diese Variable rein geschrieben.

    Das selbe Problem hat du auch bei deiner letzten Version:


    Hier so sieht mein Script aus :

    Auch hier versuchst du den Wert von $alt auszulesen und in 'vorher' rein zu schreiben, aber 'alt' wurde da drüber nirgends gesetzt.

    Wie gesagt werden Scripts immer von oben nach unten abgearbeitet (auch Python) - das hüpft nicht willkürlich in den Zeilen umher und sucht sich irgendwas zusammen..

    Auch setzt du zB PORT aber verwendest das nirgends.

    Deine beiden if Schleifen bringen so jedenfalls nichts, da $neu zu dem Zeitpunkt immer 1 enthält und $alt immer 0.

    'date' brauchst du auch nicht in eine Variable schreiben um diese später abzurufen, du kannst den Befehl auch direkt in der echo Zeile einfügen und die Rückgabe verwenden..
    Ich würde dir auch empfehlen anstatt einen Befehl mit `ls` zu umschließen um dessen Rückgabe zu verwenden, lieber $(ls) zu nutzen, das macht es wie ich finde einfacher und übersichtlicher.

    Also wenn, dann sollte/könnte das bash Script wie folgt aussehen:

    Was da Zeile-für-Zeile passiert ist im Prinzip folgendes:

    • PORT beinhaltet den GPIO pin der abgefragt werden soll
    • Da beim starten des Scripts der vorherige Status noch nicht bekannt ist, wird previous_state auf -1 gesetzt um eindeutiger zu sein, denn 0 könnte missverstanden werden...
    • while true .. ist eine Schleife die sich so lange im Kreis dreht bis ein Fehler innerhalb der Schleife auftritt, oder diese mit break unterbrochen wird.
    • Der aktuelle Status des GPIOs wird in current_state hinterlegt
    • Die nächste Zeile ist eine verkürze if Schleife die man als 'Einzeiler' so schreiben kann, ohne 'if' am Anfang oder 'fi' am Ende. Dort wird geprüft ob previous_state noch -1 enthält, was eben ein Hinweis auf den ersten Durchlauf ist, und wenn das der Fall ist wird die Variable mit $current_state befüllt.
    • Dann wird geprüft ob $current_state nicht-gleich $previous_state ist, nur wenn dem so ist wird das innerhalb der if Schleife abgearbeitet.

      • Trifft die erste if-Bedingung zu, wird geprüft ob $current_state gleich 1 ist, was anzeigen sollte das der Kontakt geschlossen, beziehungsweise ein Reedswitch geöffnet ist. Ist das der Fall wird etwas ausgeben usw - das zu erklären erspar ich mir jetzt :D
      • Wenn $current_state gleich 0 ist, wird der Spies halt umgedreht verarbeitet... Besser wäre hier aber ein " if ... elif " zu nutzen denn wenn die Bedingung bereits bei der ersten Schleife zu traf brauch man diesen nicht noch mal prüfen:
        Code
        if [ "$current_state" = 1 ]; then
              echo "Tuer geoeffnet"
            elif [ "$current_state" = 0 ]; then
              echo "Tuer geschlossen"
            fi
    • Am Ende der while-Schleife wird der Wert von $current_state in die Variable previous_state gesetzt damit dies beim nächsten Durchlauf verwertet werden kann.
    • Die Schleife pausiert für 5 Sekunden. Nach Ablauf der Zeit beginnt die Schleife wieder von vorne.
    • Ende der while-Schleife-Markierung

    Es gibt aber wie immer mehrere Möglichkeiten - auch das hier kann man noch besser/schöner/effektiver machen..
    Ich würde auch eher dazu tendieren auf wiringPI zu verzichten und stattdessen den GPIO-Wert direkt aus /sys/class/gpio/ auszulesen:

    "bash"

    Allerdings sorgt das sleep dafür das innerhalb dieser Zeit keine Änderung festgestellt werden kann, das Script also genau so wie in Python blockiert wird. Öffnet und schließt sich die Tür innerhalb 5 Sekunden kann das nicht erfasst werden. Den sleep aber tiefer zu stellen verursacht mehr CPU-Last. Deshalb würde ich das eher über Python mit Interrupt umsetzen...


    Aber wie gesagt frag ich mich wieso du das nicht direkt in dem /home/pi/mailpositive.py machst :huh:
    Du hast doch >> hier << das Script gepostet, oder nicht? Und dein Ziel ist jetzt nur dann eine Email zu verschicken wenn sich der Zustand des GPIO's verändert? Das könnte man ziemlich einfach direkt in dem Python Script realisieren:

    &quot;python&quot;

    [code=php]
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    #
    # v0.1 by meigrafd 04.2015
    #
    import smtplib
    import time, sys, signal
    import RPi.GPIO as GPIO

    #---------------------------------------------------------------------
    GPIOpin = 4

    # only one of following:
    PULL = GPIO.PUD_DOWN #GPIO -> GND
    #PULL = GPIO.PUD_UP #GPIO -> 3V3

    mailServer = 'pop.gmail.com'
    mailPort = 587
    mailLogin = 'xxx@gmail.com'
    mailPass = 'xyz'
    mailSendFrom = mailLogin
    mailSendTo = 'target@email.com'
    mailTLS = True
    mailDebug = False
    #---------------------------------------------------------------------

    def sendemail(from_addr, to_addr, subject, message):
    try:
    header = 'From: %s\n' % from_addr
    header+= 'To: %s\n' % to_addr
    header+= 'Subject: %s\n\n' % subject
    message = header + message
    conn = smtplib.SMTP(mailServer, mailPort)
    if mailDebug:
    conn.set_debuglevel(True) #show communication with the server
    if mailTLS:
    conn.starttls()
    conn.login(mailLogin, mailPass)
    error = conn.sendmail(from_addr, to_addr, message)
    if not error:
    print "Successfully sent email"
    except Exception, e:
    print "\nSMTP Error: " + str(e)
    finally:
    if conn:
    conn.quit()

    def interrupt_event(pin):
    zeit = time.strftime('%d.%m.%Y %H:%M:%S')
    if GPIO.input(pin): # if gpioPin == 1
    print "{} Rising edge detected on {}".format(zeit, pin)
    msg='Ihr Raspberry Pi hat den Status 1 , was soviel bedeutet wie das die Tür offen ist. Eventuell sind Ninjas in ihr Haus eingebrochen und vergreifen sich jetzt an ihren Oreo Keksen.'
    sendemail(mailSendFrom, mailSendTo, 'Türbenachrichtigung', msg)
    else:
    print "{} Falling edge detected on {}".format(zeit, pin)

    if __name__ == '__main__':
    try:
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(GPIOpin, GPIO.IN, pull_up_down = PULL)
    GPIO.add_event_detect(GPIOpin, GPIO.BOTH, callback=interrupt_event, bouncetime=100)
    #keep script running
    signal.pause()
    except (KeyboardInterrupt, SystemExit):
    print 'Quit'
    GPIO.cleanup()
    [/php]

    ..fraglich wär nur ob du gewillt bist zu verstehen was da passiert um dabei auch was zu lernen :s

  • Ups ich hab das garnicht gelesen es tut mir leid ;( habs aber selbst gelöst und als Projekt veröffentlicht

Jetzt mitmachen!

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