Forum: PC-Programmierung Raspberry Script per php ausführen


von Bernd (Gast)


Angehängte Dateien:

Lesenswert?

ich habe eine LED-Matrix an den einen Raspberry Pi angeschlossen und ein 
PythonProgramm geschrieben, welches die Matrix angesteuert. Das Programm 
wird über Pipes angesteuert. Zum Anlegen des Fifo, zum Verhindern dass 
das Programm mehrmals gestartet wird und zum Starten des Pythonprogramms 
habe ich ein extra Script geschrieben. Das funktioniert auch alles 
wunderbar.

Nur wie kann ich das startScript über php aufrufen?

echo (exec ('./scripts/ws2812Start.sh'));
So funktioniert es leider nicht, auch wenn ich es mit sudo versuche.

Die Scripte sind auch alle freigegeben:

pi@starDeko:/var/www/html/starDeko $ ls -l scripts
total 36
-rwxrwxrwx 1 root root 7360 Oct 29 22:33 ws2812ctrl1.py
-rwxrwxrwx 1 root root  281 Oct 31 16:13 ws2812Start.sh
pi@starDeko:/var/www/html/starDeko $

Kann jemand helfen und mir sagen, wie das mit dem Aufrufen über PHP 
funktioniert?

von T.roll (Gast)


Lesenswert?

Bernd schrieb:
> So funktioniert es leider nicht

Und die Fehlermeldung zeigst du uns nicht, weil...?

Bernd schrieb:
> Die Scripte sind auch alle freigegeben:
Auch wenn diese "Lösung" immer wieder im Internet irgendwo erscheint:
Die Rechte auf 777 stellen ist eine schlechte Lösung. Setz sie passend.

PHP wird in einem anderen Ordner unterwegs sein.

von Bernd (Gast)


Lesenswert?

es kommt leider keine Fehlermeldung.

von jz23 (Gast)


Lesenswert?

Bernd schrieb:
> es kommt leider keine Fehlermeldung.

Was kommt denn von der Seite? Drück mal Strg+U (In Firefox und Chrome 
zumindest), dann wird dir der Quellcode der Seite angezeigt, bzw. die 
Serverantwort als Plain-Text.

von Bernd (Gast)


Lesenswert?

1
<!--
2
    +++++ starDeko Testseite +++++   
3
-->
4
5
<html>
6
 <head>
7
  <meta charset="utf-8" />
8
  <title> Star-Deko </title> 
9
  <link rel= "stylesheet" hre= "style.css" />
10
 </head>
11
12
 WS2812ctrl starten 
13
 
14
 <body>
15
   <center>
16
   <div id= "ueberschrift">
17
    <center><b>Star-Deko<br>- erster Test -</b>
18
   </div> <!--- ueberschrift ---> 
19
   <br><br>
20
   <form action = "index.php" method = "POST" >
21
    <center>
22
  <table width= "90%">
23
   <tr><td><input type = "submit" name = "aStart" value = "** Start **"></td></tr>
24
   <tr><td><input type = "submit" name = "aZufall1" value = "** Zufall1 **"></td></tr>
25
   <tr><td><input type = "submit" name = "aZufall2" value = "** Zufall2 **"></td></tr>
26
   <tr><td><input type = "submit" name = "aZufall3" value = "** Zufall3 **"></td></tr>
27
   <tr><td><input type = "submit" name = "aStop" value = "**  Stop  **"></td></tr>
28
  </table>
29
   </form>
30
   
31
   <br><br><br><br>
32
33
   <div id= "footer">
34
35
     CPU-Temp: 33.1°C     <br>--------------<br>
36
 
37
 </body>
38
39
40
41
</html>

Die Ausgabe "ws2812ctrl starten" kommt vom StartScript & die Datei fifo1 
wird auch angelegt.
Nur der Aufruf des PythonProgramms im starScript funktioniert nicht:

# ws2812ctrl starten
sudo ./scripts/ws2812ctrl1.py &

sudo ps zeigt mir auch keinen gestarteten Prozess an.

Wo kann ich überhaupt anfangen den Fehler zu finden?
Oder was kann ich noch probieren?

von jz23 (Gast)


Lesenswert?

Dann wird dein Skript doch ausgeführt?
Du solltest aber vielleicht lieber exec_shell() statt exec() verwenden, 
letzteres gibt nicht die komplette Ausgabe des Befehls zurück.

von Bernd (Gast)


Lesenswert?

Bei shell_exec wird die Seite überhaupt nicht mehr geladen.

Der Seitenquelltext sieht dann so aus:
<!--
    +++++ starDeko Testseite +++++
-->

<html>
 <head>
  <meta charset="utf-8" />
  <title> Star-Deko </title>
  <link rel= "stylesheet" hre= "style.css" />
 </head>

von Finn S. (scooter757)


Lesenswert?

Vielleicht hilft ein absoluter pfad zum Script.

von T.roll (Gast)


Lesenswert?

Bernd schrieb:
> Bei shell_exec wird die Seite überhaupt nicht mehr geladen.

Dann schau was im error_log steht.
PHP kann auch direkt Fehler anzeigen, z.B. mit display_errors

von c.m. (Gast)


Lesenswert?

1. das script wir unter php mit dem benutzer ausgeführt, unter dem der 
http-server läuft. darf der user "httpd" (oder ähnlich) die im python 
script stehenden GPIO's ansteuern?
ruf das script mal in der shell als http-user auf und schau obs geht.

2. keine relativen pfade verwenden.
1
/usr/bin/python </<pfad zum script>/ws2812ctrl1.py

3. poste mal das php-script.

von Bernd (Gast)


Lesenswert?

<?php
  //  ----- Auswertung Tasten -----
  ini_set('display_errors', 1);
   if (isset($_POST['aStart']))
   {
    echo "Start";
    echo exec('./scripts/ws2812Start.sh &');
   }
   else if (isset($_POST['aZufall1']))
   {
    echo "EINS";
   }
   else if (isset($_POST['aZufall2']))
   {
     echo "ZWEI";
   }
   else if (isset($_POST['aZufall3']))
   {
     echo "DREI";
   }
   else if (isset($_POST['aStop']))
   {
     echo "STOP";
   }
 ?>

so sieht das PHP-Script jetzt aus.

Der User müsste eigentlich www-data sein, aber mit dem kann ich mich auf 
der Konsole nicht anmelden.

von Bernd (Gast)


Lesenswert?

Und in der error.log stehen nur alte Fehler von vor ein paar Wochen.

von Soeren K. (srkeingast)


Lesenswert?

Bernd schrieb:
> Der User müsste eigentlich www-data sein, aber mit dem kann ich mich auf
> der Konsole nicht anmelden.

Sicher?

# su -s /bin/bash www-data

von Bernd (Gast)


Lesenswert?

su -s /bin/bash www-data
fragt nach einem Passwort. www-data hat irgendwie kein Passwort.

von Soeren K. (srkeingast)


Lesenswert?

Fragt nach dem sudoer/root Passwort!

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Bernd schrieb:
> Und in der error.log stehen nur alte Fehler von vor ein paar Wochen.

Dann hast du das richtige wohl nicht gefunden. Oder du hast kein PHP im 
Webserver und der Kram wird schlicht ignoriert.

Wenn du ein PHP baust, das absichtlich einen Fehler enthält, und du dann 
nirgends etwas darüber siehst, dann suchst du an der falschen Stelle.

Fehler landen nur im Apache-Log, wenns das darin integrierte PHP ist. 
Wird PHP aber beispielsweise über fcgi angesprochen, dann gibts dazu ein 
eigenes Log.

PHP Scripts kann man testweise auch in der Kommandozeile aufrufen, wenn 
php-cli installiert ist.

von Soeren K. (srkeingast)


Lesenswert?

Also wichtig wäre, um andere Fehler auszuschließen:

- Was passiert wenn das py-Script als www-data gestartet wird?
- Du könntest auch noch stderr umleiten: exec('./scripts/ws2812Start.sh 
2>&1');
- Hast du im .sh Script (hast du leider nicht gepostet) alle Pfade 
entsprechend gesetzt? Hast du den direkten Pfad zur Python-Binary 
angegeben?
- Statt ./scripts/ im Idealfall den absoluten Pfad angeben

von Bernd (Gast)


Lesenswert?

Ich habs jetzt mal als www-data gestartet:

Aufruf ohne sudo:

www-data@starDeko:~/html/starDeko$ ./scripts/ws2812ctrl1.py
Failed to create mailbox device
: Operation not permitted
Traceback (most recent call last):
  File "./scripts/ws2812ctrl1.py", line 269, in <module>
    leds.begin()
  File 
"/usr/local/lib/python3.4/dist-packages/rpi_ws281x-1.0.0-py3.4-linux-arm 
v                           6l.egg/neopixel.py", line 115, in begin
    raise RuntimeError('ws2811_init failed with code {0} 
({1})'.format(resp, mes                          sage))
RuntimeError: ws2811_init failed with code -9 (Failed to create mailbox 
device)
Segmentation fault

Aufruf als www-data mit sudo:

www-data@starDeko:~/html/starDeko$ sudo ./scripts/ws2812ctrl1.py

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for www-data:
Sorry, try again.
[sudo] password for www-data:
Sorry, try again.
[sudo] password for www-data:

Sorry, try again.
sudo: 3 incorrect password attempts

bei dem Passwort für www-data bin ich immer noch überfordert...


Wenn ich das script mit dem StandardBenutzer pi ohne sudo aufrufe:

pi@starDeko:/var/www/html/starDeko $ ./scripts/ws2812ctrl1.py &
[2] 2136
[1]   Exit 127                ./scripts/ws2812ctrl.py
pi@starDeko:/var/www/html/starDeko $ Can't open /dev/mem: Permission 
denied
Traceback (most recent call last):
  File "./scripts/ws2812ctrl1.py", line 269, in <module>
    leds.begin()
  File 
"/usr/local/lib/python3.4/dist-packages/rpi_ws281x-1.0.0-py3.4-linux-arm 
v6l.egg/neopixel.py",  line 115, in begin
    raise RuntimeError('ws2811_init failed with code {0} 
({1})'.format(resp, message))
RuntimeError: ws2811_init failed with code -5 (mmap() failed)

von Bernd (Gast)


Lesenswert?

Das .sh-Script sieht so aus:

#!/bin/bash
echo "WS2812ctrl starten"

# falls ws2812Script schon läuft
sudo killall -s 9 ws2812ctrlpy

# bestehende fifo löschen
rm fifo1

# fifo anlegen und freigeben
mkfifo fifo1
chmod a+rw fifo1

# ws2812ctrl starten
sudo ./scripts/ws2812ctrl1.py &
#echo -n "." >fifo1 &

von Bernd (Gast)


Lesenswert?

beim stderr umleiten kommt:

Startsudo: no tty present and no askpass program specified

von imonbln (Gast)


Lesenswert?

Bernd schrieb:
> ich habe eine LED-Matrix an den einen Raspberry Pi angeschlossen
> und ein
> PythonProgramm geschrieben, welches die Matrix angesteuert. Das Programm
> wird über Pipes angesteuert. Zum Anlegen des Fifo, zum Verhindern dass
> das Programm mehrmals gestartet wird und zum Starten des Pythonprogramms
> habe ich ein extra Script geschrieben. Das funktioniert auch alles
> wunderbar.

Ich schlage mal eine radikalen Systemumbau vor :). mach aus den Python 
eine Flask Application, lass denn ganzen Pipe | fifo foo weg und starte 
deine deine Flask Application wie jeden anderen Service. Jetzt kann dein 
PHP Script  das Python mit einfachen GET/POST requests steuern.
Der Vorteil ist je nach dein Kenntnissen und einsatz kann PHP jetzt auch 
Einfluss auf die LED-Matrix nehmen und da deine Python Application in 
immer läuft musst du dich auch nicht mehr um Synchronisation zwischen 
den einzelnen Instanzen kümmern, es wird ja nur eine vom System 
gestartet.

Theoretisch kannst du so deiner LED-Martix sogar eine REST-API 
spendieren.

von c.m. (Gast)


Lesenswert?

Bernd schrieb:
> Das .sh-Script sieht so aus:
>
> #!/bin/bash
> echo "WS2812ctrl starten"
>
> # falls ws2812Script schon läuft
> sudo killall -s 9 ws2812ctrlpy
>
> # bestehende fifo löschen
> rm fifo1
>
> # fifo anlegen und freigeben
> mkfifo fifo1
> chmod a+rw fifo1
>
> # ws2812ctrl starten
> sudo ./scripts/ws2812ctrl1.py &
> #echo -n "." >fifo1 &

darf www-data denn per sudo killall aufrufen?
"ws2812ctrlpy", wirklich?
wo genau liegt fifo1 denn? unter /var/www/?
wo genau soll fifo1 denn angelegt werden? unter /var/www/?
darf www-data der sudo python aufrufen, und funtioniert das ermitteln 
des interpreters mittels angabe von ./scripts/ws2812ctrl1.py überhaupt?

wenn www-data kein passwort hat, musst du dem benutzer eins geben. mit 
"passwd". außerdem kann es sein, das der benutzer /bin/false als shell 
hat (steht in /etc/passwd), das kann man mit "usermod" ändern.

> Wenn ich das script mit dem StandardBenutzer pi ohne sudo aufrufe:
>
> pi@starDeko:/var/www/html/starDeko $ ./scripts/ws2812ctrl1.py &
> [2] 2136
> [1]   Exit 127                ./scripts/ws2812ctrl.py
> pi@starDeko:/var/www/html/starDeko $ Can't open /dev/mem: Permission
> denied

das gleiche problem wird www-data haben.

von Bernd (Gast)


Lesenswert?

www-data darf eigentlich nichts. Ich habe noch mit der sudoers 
experimentiert, bin aber auch nicht weitergekommen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.