PHP: shell_exec wird nur per CLI, nicht aber über Browser aufgerufen

maalik

Benutzer
Mitglied seit
05. Feb 2016
Beiträge
705
Punkte für Reaktionen
11
Punkte
38
Hallo zusammen,

ich habe eine Webseite, die via PHP mit shell_exec ein Python-Skript aufruft, dieses generiert den Rohtext für ein SVG und übergibt das am Ende wieder PHP, welches das SVG dann mit canvas malt.

Seit 2 Wochen geht das allerdings nicht mehr, ich vermute seit dem letzten DSM-Update.

Das merkwürdige: Wenn ich via SSH
Code:
php74 action.php
das Skript aufrufe, dann geht alles und das SVG wird im HTML hinzugefügt.

Über den Browser geht das nicht. $command = "python3 file.py args"" beinhaltet wird noch korrekt gefüllt, aber $svg = shell_exec($command); macht dann schlichtweg gar nichts mehr. Wenn ich anschließend mit echo $svg; was ausgeben will, wird da im Browser auch nichts ausgegeben; auf dem CLI schon.
Klingt also irgendwie nach folgendem Problem, die genannten Dinge sind aber alle ausgestellt.
https://stackoverflow.com/a/20124768


Wenn ich jetzt allerdings eine Datei test.php mit Inhalt

Code:
<?php
exec('ls',$out,$rval);
echo "Output:<hr />";
print "<pre>"; print_r($out); print "</pre>";
echo "Return Value:<hr />";
echo $rval;
?>

erstelle, dann geht alles.

Wo liegt der Fehler? Ich vermute irgendwie, dass PHP das Python Skript nicht richtig ausführt. PHP Error Report ist aktiv, aber da bekomme ich nirgends eine Fehlermeldung.

Wo soll ich anfangen zu suchen?

LG
Felix
 

luddi

Benutzer
Sehr erfahren
Mitglied seit
05. Sep 2012
Beiträge
3.242
Punkte für Reaktionen
586
Punkte
174
Kann das mit den Berechtigungen der script files zu tun haben? Über CLI führst du den Befehlt vermutlich als admin (root) aus. Wenn man über den Browser kommt wird das vom System User "http" ausgeführt.
 

maalik

Benutzer
Mitglied seit
05. Feb 2016
Beiträge
705
Punkte für Reaktionen
11
Punkte
38
Moin luddi,

eigentlich hatte ich das ausgeschlossen, weil das andere Testskript ja bei gleichen Berechtigungen funktionierte. Ich hab jetzt aber mal folgendes getestet:


Code:
sudo -u root php action.php -> GEHT
sudo -u http php action.php -> GEHT NICHT!


Okay, wir kommen dem näher. Aber wo genau ist das Problem? Ich habe aktuell alle Dateien auf chown http:http und chmod 777, also dürfte das doch eigentlich kein Grund mehr sein.
Hat Synology mit einem Update vielleicht was geändert, dass http generell keine shell_exec mehr ausführen darf?
Oder eine Web-Station-Angelegenheit?

Grübel grübel.
 

maalik

Benutzer
Mitglied seit
05. Feb 2016
Beiträge
705
Punkte für Reaktionen
11
Punkte
38
Eine Idee: Kann es sein, dass http keine Rechte hat, das bei DSM 7 integrierte Python 3 zu nutzen? Wie teste ich das?
 

luddi

Benutzer
Sehr erfahren
Mitglied seit
05. Sep 2012
Beiträge
3.242
Punkte für Reaktionen
586
Punkte
174
Bekommst du eine Fehlermeldung wenn du es als http sudo -u http php action.php ausführen möchtest?
 

maalik

Benutzer
Mitglied seit
05. Feb 2016
Beiträge
705
Punkte für Reaktionen
11
Punkte
38
Ha, ja, jetzt sehe ich das Problem:
Code:
Traceback (most recent call last):
  File "svg_to_pdf.py", line 4, in <module>
    from bs4 import BeautifulSoup
ImportError: cannot import name 'BeautifulSoup' from 'bs4' (unknown location)

Scheinbar nutzt http eine andere Python-Environment als root. Bei root ist das nämlich installiert.

Grmpf das hatte ich schonmal, aber mit DSM 7 haben die glaube ich die Art und Weise wie man mit pip Pakete installiert geändert. Hast du das gerade auf dem Schirm wie das nochmal geht?
 

maalik

Benutzer
Mitglied seit
05. Feb 2016
Beiträge
705
Punkte für Reaktionen
11
Punkte
38
Okay, habe es gelöst. Habe erst eine venv erstellt:

Code:
python3 -m venv bs4-env

Danach aktiviert:
Code:
source bs4-env/bin/activate

Für die erstelle venv dann chown http:http gesetzt

Und dann im Skript entsprechend nicht mehr python3 sondern bs4-env/bin/python3 aufgerufen.

Bleibt die Frage: Warum ruft http (vor meinen Änderungen) eine andere Python Umgebung auf als root?
 

luddi

Benutzer
Sehr erfahren
Mitglied seit
05. Sep 2012
Beiträge
3.242
Punkte für Reaktionen
586
Punkte
174
Bleibt die Frage: Warum ruft http (vor meinen Änderungen) eine andere Python Umgebung auf als root?
Die Frage ist ob dem user http der Pfad für python3 bekannt ist. Das gleiche hatte ich eben für php vermutet.
Vielleicht würde hier im Script auch folgendes funktionieren wenn man mit absoluten Pfaden zur jeweiligen binary arbeitet.
  • /usr/local/bin/php74
  • /usr/local/bin/python3.9
 

maalik

Benutzer
Mitglied seit
05. Feb 2016
Beiträge
705
Punkte für Reaktionen
11
Punkte
38
Hm, also unter
Code:
/usr/local/bin
habe ich nur python2 und python 2.7.
 

luddi

Benutzer
Sehr erfahren
Mitglied seit
05. Sep 2012
Beiträge
3.242
Punkte für Reaktionen
586
Punkte
174
Aber das Paket python3 hast du über das Paket-Zentrum installiert?

Was gibt denn deine Konsole als root bei which python3 aus?

In meinem Fall wäre das:
/bin/python3 und das ist ein symbolic link auf /bin/python3.8.
 

maalik

Benutzer
Mitglied seit
05. Feb 2016
Beiträge
705
Punkte für Reaktionen
11
Punkte
38
Nein, in DSM 7 gibt es kein Python3 mehr im Paketzentrum, das kommt automatisch mit DSM.

which python sagt mir /bin/python3

Wenn ich in der action.php /bin/python3 aufrufe, bekomme ich wieder die Meldung, dass bs4 fehlt.
 

luddi

Benutzer
Sehr erfahren
Mitglied seit
05. Sep 2012
Beiträge
3.242
Punkte für Reaktionen
586
Punkte
174
Scheinbar nutzt http eine andere Python-Environment als root. Bei root ist das nämlich installiert.
Hmm... das ist durchaus interessant... :unsure:

Wie bekommt man das heraus und wie kann man die Umgebung vergleichen?
 

maalik

Benutzer
Mitglied seit
05. Feb 2016
Beiträge
705
Punkte für Reaktionen
11
Punkte
38
Das wüsste ich auch gerne. Das sind Dinge, mit denen ich mich bei Python zum Glück nie mit beschäftigen musste.
 


 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat