2015-03-02 33 views
5

Próbuję napisać mały program Pythona do wyłączenia lub Restartuj mój Malinowy PI sterowany przez przycisk podłączony do GPIO. Program może pokazywać aktualny stan malinowego PI (uruchamianie, bieganie, zatrzymywanie, ponowne uruchamianie) za pomocą dwóch diod LED. Program python jest wykonywany jako demon, uruchamiany przez skrypt bash init.d (napisany przy użyciu /etc/init.d/skeleton).Wyślij wiadomość do skryptu w języku Python

Teraz mogę uruchomić/zatrzymać/zweryfikować status demona, a demon może sprawdzić wejście, w którym przycisk jest podłączony, aby wykonać polecenie "shutdown -h now" lub "shutdown -r now".

Aby pokazać aktualny stan malinowego PI, pomyślałem o wysłaniu wiadomości do demona, używając jakiegoś skryptu w wersjach runlevels, aby zmienić status diod. Ale nie wiem, jak otrzymać wiadomość w programie Pythona.

Ktoś może mi pomóc?

Dzięki.

Odpowiedz

6

Istnieje kilka metod, aby wysłać wiadomość od jednego skryptu/aplikacji do drugiego:

dla ciebie aplikacji prawidłowym sposobem jest użycie nazwanego potoku. Utwórz go za pomocą os.mkfifo, otwórz go tylko do odczytu w swojej aplikacji Pythona, a następnie poczekaj na wiadomości na nim.

Jeśli chcesz aplikację aby zrobić kolejny rzeczy czekając, ja polecam Ci otworzyć rurę w trybie non-blocking szukać dostępności danych bez blokowania skryptu, jak w poniższym przykładzie:

import os, time 

pipe_path = "/tmp/mypipe" 
if not os.path.exists(pipe_path): 
    os.mkfifo(pipe_path) 
# Open the fifo. We need to open in non-blocking mode or it will stalls until 
# someone opens it for writting 
pipe_fd = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK) 
with os.fdopen(pipe_fd) as pipe: 
    while True: 
     message = pipe.read() 
     if message: 
      print("Received: '%s'" % message) 
     print("Doing other stuff") 
     time.sleep(0.5) 

wtedy można wysyłać wiadomości ze skryptów bash przy użyciu polecenia

echo "your message" > /tmp/mypipe

EDIT: nie mogę się select.select działa poprawnie (użyłem go tylko w programach C) więc zmieniłem rekomendację na tryb bez blokady.

+0

Zbiorniki dużo! Spróbuję sposobu "nazwanego potoku" ... – EffegiWeb

+0

Nie rozumiem użycia funkcji 'select.select()' w przypadku sprawdzania pliku. Czy możesz mi pomóc z przykładem? Muszę czekać na wiadomości w nieskończonej pętli. – EffegiWeb

+0

Nie mogę uzyskać select.select działa poprawnie (użyłem go tylko w programach C), więc zmieniłem swoje zalecenie na tryb nie-bloking i dodałem przykład. – Patxitron

0

Czy ta wersja jest wygodniejsza? Z kosztami with w pętli ? W ten sposób, cały inny kod wewnątrz pętli jest wykonywany nawet w przypadku błędu w zarządzaniu plikami rur. Ostatecznie mogę użyć try: costuct do przechwycenia błędu.

import os, time 

pipe_path = "/tmp/mypipe" 
if not os.path.exists(pipe_path): 
    os.mkfifo(pipe_path) 
# Open the fifo. We need to open in non-blocking mode or it will stalls until 
# someone opens it for writting 
pipe_fd = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK) 

while True: 
    with os.fdopen(pipe_fd) as pipe: 
     message = pipe.read() 
     if message: 
      print("Received: '%s'" % message) 

    print("Doing other stuff") 
    time.sleep(0.5) 
+0

Nie jest bezpieczne, aby fdopen wiele razy rury/plik otwarty z os.open. Gdy instrukcja "with" wykracza poza zakres (zdanie "Robiąc inne rzeczy") zamyka to deskryptor pliku i nie można go ponownie otworzyć. Również zamykasz rurę, podczas gdy inny proces jest podłączony, proces ten odbierze sygnał SIGPIPE i najprawdopodobniej zakończy jego wykonanie. Powinieneś utrzymywać rurę otwartą przez cały czas, gdy jesteś w pętli. – Patxitron

+0

@Patxitron: Dziękuję za informacje. – EffegiWeb