Exécuter un script Python depuis PHP

114

J'essaie d'exécuter un script Python à partir de PHP en utilisant la commande suivante:

exec('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');

Cependant, PHP ne produit tout simplement aucune sortie. Le rapport d'erreur est défini sur E_ALL et display_errors est activé.

Voici ce que j'ai essayé:

  • J'ai utilisé python2, /usr/bin/python2et python2.7au lieu de/usr/bin/python2.7
  • J'ai également utilisé un chemin relatif au lieu d'un chemin absolu qui n'a rien changé non plus.
  • J'ai essayé d' utiliser les commandes exec, shell_exec, system.

Cependant, si je cours

if (exec('echo TEST') == 'TEST')
{
    echo 'exec works!';
}

cela fonctionne parfaitement bien shutdown nowsans rien faire.

PHP a les autorisations pour accéder et exécuter le fichier.

EDIT: Grâce à Alejandro, j'ai pu résoudre le problème. Si vous rencontrez le même problème, n'oubliez pas que votre serveur Web ne fonctionnera probablement pas en tant que root. Essayez de vous connecter en tant qu'utilisateur de votre serveur Web ou en tant qu'utilisateur avec des autorisations similaires et essayez d'exécuter les commandes vous-même.

Compte abandonné
la source
Visitez d'abord ce numéro stackoverflow.com/questions/21659637/... Si ce n'est pas résolu et que vous rencontrez des problèmes comme In Case si vous êtes bloqué avec des importations ou tty ou si aucun askpass ne fonctionne, veuillez consulter ce lien pour obtenir des détails sur les étapes à suivre pour l'exécuter. stackoverflow.com/a/57978771/9470457 Merci !!!
3rdi

Réponses:

159

Testé sur Ubuntu Server 10.04. J'espère que cela vous aidera également sur Arch Linux.

En PHP, utilisez la fonction shell_exec :

Exécutez la commande via le shell et renvoyez la sortie complète sous forme de chaîne.

Il renvoie la sortie de la commande exécutée ou NULL si une erreur s'est produite ou si la commande ne produit aucune sortie.

<?php 

$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;

?>

Dans le fichier Python test.py , vérifiez ce texte en première ligne: (voir shebang expliquer) :

#!/usr/bin/env python

De plus, le fichier Python doit avoir les privilèges corrects (exécution pour l'utilisateur www-data / apache si le script PHP s'exécute dans le navigateur ou curl) et / ou doit être "exécutable". De plus, toutes les commandes du .pyfichier doivent avoir les privilèges corrects:

Pris du manuel php :

Juste un petit rappel pour ceux qui essaient d'utiliser shell_exec sur une plate-forme de type Unix et qui n'arrivent pas à le faire fonctionner. PHP s'exécute en tant qu'utilisateur Web sur le système (généralement www pour Apache), vous devez donc vous assurer que l'utilisateur Web a des droits sur les fichiers ou répertoires que vous essayez d'utiliser dans la commande shell_exec. Sinon, il ne semble rien faire.

Pour rendre exécutable un fichier sur des plates-formes de type Unix :

chmod +x myscript.py
Alejandro Quiroz
la source
6
Merci, ça a fait l'affaire! Il y avait un autre problème - l'utilisateur Apache n'a pas pu exécuter une commande dans le script Python mais j'ai pu résoudre ce problème en utilisant sudo et en ajoutant une exception pour mon script au fichier sudoers. Merci encore! :)
Compte abandonné
1
Je suis confronté au même problème que l'utilisateur apache, pouvez-vous me guider?
Emma du
1
J'ai utilisé votre réponse, il exécute le script python bien mais je ne peux pas faire écho aux résultats, rien n'apparaît dans la page Web, pouvez-vous m'aider.
Hamdi Charef
1
"#! / usr / bin / env python" sur la première ligne m'a fait l'affaire. Génial!
C3PO
1
Pour OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); ou:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
Cyborg
24

Je recommande d'utiliser passthruet de gérer directement le tampon de sortie:

ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean(); 
Niklas Lindblad
la source
16

Si vous souhaitez connaître l'état de retour de la commande et obtenir la stdoutsortie complète, vous pouvez réellement utiliser exec:

$command = 'ls';
exec($command, $out, $status);

$outest un tableau de toutes les lignes. $statusest le statut de retour. Très utile pour le débogage.

Si vous voulez également voir la stderrsortie, vous pouvez soit jouer avec proc_open, soit simplement ajouter 2>&1à votre fichier$command . Ce dernier est souvent suffisant pour faire fonctionner les choses et bien plus rapidement pour «mettre en œuvre».

kqw
la source
8

Alejandro l'a cloué, ajoutant une clarification à l'exception (Ubuntu ou Debian) - je n'ai pas le représentant à ajouter à la réponse elle-même:

fichier sudoers: sudo visudo

exception ajoutée: www-data ALL=(ALL) NOPASSWD: ALL

Colin Miles
la source
7
Cela ne semble pas efficace pour ajouter des www-data aux sudoers, et donne à apache plus d'autorisations dont il a besoin. Donner des autorisations www-data sur le script que vous exécutez serait suffisant.
JasonRDalton
Bonne idée, mais pourrait certainement rendre votre système vulnérable. Je suis d'accord avec @JasonRDalton
Reed le
6

Pour clarifier la commande à utiliser en fonction de la situation

exec() - Exécuter un programme externe

system() - Exécuter un programme externe et afficher la sortie

passthru() - Exécuter un programme externe et afficher la sortie brute

Source: http://php.net/manual/en/function.exec.php

Agnel Vishal
la source
4

Dans mon cas, j'avais besoin de créer un nouveau dossier dans le wwwrépertoire appelé scripts. Dans scriptsj'ai ajouté un nouveau fichier appelé test.py.

J'ai ensuite utilisé sudo chown www-data:root scriptset sudo chown www-data:root test.py.

Ensuite, je suis allé dans le nouveau scriptsrépertoire et utilisé sudo chmod +x test.py.

Mon fichier test.py ressemble à ceci. Notez les différentes versions de Python:

#!/usr/bin/env python3.5
print("Hello World!")

Depuis php, je fais maintenant ceci:

$message = exec("/var/www/scripts/test.py 2>&1");
print_r($message);

Et vous devriez voir: Hello World!

Tim Hallman
la source
3

Les méthodes ci-dessus semblent complexes. Utilisez ma méthode comme référence.

J'ai ces deux fichiers:

  • run.php

  • mkdir.py

Ici, j'ai créé une page HTML qui contient un GO bouton. Chaque fois que vous appuyez sur ce bouton, un nouveau dossier est créé dans le répertoire dont vous avez mentionné le chemin.

run.php

<html>
 <body>
  <head>
   <title>
     run
   </title>
  </head>

   <form method="post">

    <input type="submit" value="GO" name="GO">
   </form>
 </body>
</html>

<?php
	if(isset($_POST['GO']))
	{
		shell_exec("python /var/www/html/lab/mkdir.py");
		echo"success";
	}
?>

mkdir.py

#!/usr/bin/env python    
import os    
os.makedirs("thisfolder");
SMshrimant
la source
1

C'est tellement trivial, mais je voulais juste aider tous ceux qui ont déjà suivi la suggestion d'Alejandro mais ont rencontré cette erreur:

sh: blabla.py: commande introuvable

Si quelqu'un a rencontré cette erreur, une petite modification doit être apportée au fichier php par Alejandro:

$command = escapeshellcmd('python blabla.py');
Gérald Joshua
la source