Python script in php ausführen

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
jmr0471
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 16:14

Hallo zusammen,

mein aktuelles Problem treibt mich jetzt seit Tagen in den Wahnsinn... :oops:

Folgend mein Setup welches soweit vollständig funktioniert:
- ich rufe über eine URL ein PHP Skript auf, welches über exec() ein Python Skript auf einem Raspberry Pi ausführt
- das Python Skript macht ein Foto und schreibt die Bilddatei auf ein NAS

Nun zum Problem:
- in einem anderen PHP Skript (mount.php) versuche ich auch über exec() ein anderes Python Skript (start.py) auszuführen
mount.php
<?php
echo exec("sudo python /var/www/html/start.py 2>&1", $output);
?>

start.py
#!usr/bin/env python
from subprocess import *
check_call( 'sudo mount -t cifs //rasp-ip/photo /home/NAS2 -o user=pi,pass=pass', shell=True )


- Python Skript direkt über die Shell ausgeführt - funktioniert
- PHP Skript über die Shell ausgeführt - funktioniert
- PHP Skript über den Browser ausgeführt - funktioniert nicht, obwohl es grundsätzlich wie oben beschrieben mit PHP und Python Aufruf funktioniert
- alle Dateien liegen im /var/www/html Verzeichnis des Pi's und besitzen identische Rechte

Der exec() output liefert folgende Fehlermeldung:
subprocess.CalledProcessError: Command 'sudo mount -t cifs //rasp-ip/photo /home/NAS2 -o user=pi,pass=pass' returned non-zero exit status 32mountArray ( [0] => mount error(16): Device or resource busy [1] => Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) [2] => Traceback (most recent call last): [3] => File "/var/www/html/start.py", line 5, in [4] => check_call( 'sudo mount -t cifs //rasp-ip/photo /home/NAS2 -o user=pi,pass=pass', shell=True ) [5] => File "/usr/lib/python2.7/subprocess.py", line 186, in check_call [6] => raise CalledProcessError(retcode, cmd) [7] => subprocess.CalledProcessError: Command 'sudo mount -t cifs //rasp-pi/photo /home/NAS2 -o user=pi,pass=pass' returned non-zero exit status 32 )

Wo liegt das Problem?

Vielen Dank für jegliche Lösungsvorschläge!
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@jmr0471: Hast Du Dir die Fehlermeldung mal durchgelesen? Der entscheidende Satz: »Device or resource busy«. Mount kann man nur einmal aufrufen. Warum überhaupt PHP, wenn man doch schon Python hat? Unter /var/www/html/ sollten keine Skripte liegen. Das ist ein guter Einstieg, damit Hacker an die interne Struktur des Servers kommen. Die Shebang-Zeile des Pythonprogramms ist kaputt. *-Importe vermeiden; gib check_call explizit an. `shell=True` nicht verwenden.
jmr0471
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 16:14

Hallo Sirius3,

vielen Dank für die gut gemeinten Hinweise. Sicherheitstechnisch ein Desaster - aber der Pi ist nur vom eigenen Netz zugänglich.
Die weiteren Hinweise sind wohl auch gut gemeint, aber leider fehlen die Lösungen...

Es liegt nicht daran, dass das Laufwerk schon gemounted ist.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Sicherheitstechnisch ein Desaster - aber der Pi ist nur vom eigenen Netz zugänglich.
Das ist trotzdem keinen Entschuldigen, nachläßig bis schlampig zu programmieren.
Es liegt nicht daran, dass das Laufwerk schon gemounted ist.
Wie kommst du darauf? Genau das besagt aber die Fehlermeldung, die du gepostet hast...

Warum willst du das Laufwerk eigentlich erst einhängen, wenn das Python-Skript ausgefühjrt wird? Was spricht dagegen, dass Ding vom Booten einzuhängen?

Gruß, noisefloor
jmr0471
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 16:14

Wollte es nur zum Schreiben einhängen und dann wieder aushängen.

Schlampig ist leider was Anfänger am Besten können :( Sind alles im Netz zusammen gesuchte Code Schnipsel...

Woran es auch immer liegen mag, aber das Mounten beim Booten funktioniert genausowenig. Einzig das manuelle Einhängen funktioniert :K

Tatsächlich kommt die Fehlermeldung auch erst ab der 2. Ausführungen des Skripts, was eindeutig für Deine Vermutung spricht. Leider kann ich trotzdem nicht auf die vermeintlich eingehängte Partition zugreifen. DF -l zeigt sie mir auch nicht an, im Gegensatz zum manuellen Einhängen.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

wenn du so wie so Probleme beim Einhängen hast, solltest du diese vielleicht erst mal lösen.

Wenn du die Partitionen beim Booten nicht einhängen kannst könnte das daran liegen, dass das Netzwerk zu dem Zeitpunkt noch nicht verfügbar ist. Das sollte man über die passenden Direktiven in den entsprechenden systemd Units aber regeln können.

Wenn du nicht auf die Partition zugreifen kannst könnte das an falschen Parametern oder Rechten liegen.

Und wenn das alles funktioniert kannst du dich ja wieder dem Skript zuwenden. Vorher macht das IMHO wenig Sinn.

Gruß, noisefloor
jmr0471
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 16:14

Hallo noisefloor,

die Probleme bestehen nur beim "automatischen einhängen".
Es funktioniert einwandfrei über die shell:
- mit dem mount und umount Befehlen
- beim Ausführen des Python Skripts über die shell 'python script.py'
- beim Ausführen des php Skripts über die shell 'php script.php'

Das Bootproblem kann tatsächlich am noch nicht verfügbaren WLAN liegen. Hier habe ich allerdings bereits alle in diversen Foren vorgeschlagenen Lösungen ausprobiert und nichts funktioniert :?:

Nichts ist allerdings auch nicht ganz richtig - wenn ich versuche die Partition beim Booten einzuhängen passiert letztlich das gleiche wie beim Versuch über den Browser mit php/python. Die Partition ist zwar nicht verfügbar, ein einhängen ist allerdings auch nicht mehr möglich, da die Partition bereits eingehängt zu sein scheint.

Sehr mysteriös - zumindest für mich...

Ich vermute also das alles am gleichen Problem liegt.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

bzgl. der Verfügbarkeit des Netzwerkes: du nutzt ja scheinbar einen Raspi, dann hast du vielleicht / wahrscheinlich Raspbian Jessie oder Stretch drauf? Beide nutzen systemd und systemd kennt Direktiven, dass eine Unit erst ausgeführt wird, wenn bestimmte Bedingungen erfüllt sind (wie z.B. Netzwerk vorhanden). systemd kennt mount-Units und es gibt systemd.automount. Darüber sollte das regelbar sein, beschäftigt habe ich mich damit aber auch noch nicht.

Gruß, noisefloor
jmr0471
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 16:14

Vielen Dank nochmal. Werde mir das nochmal genau ansehen :roll: :idea:
Antworten