web-dev-qa-db-fra.com

Exécution d'un script Python à partir de PHP

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

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

Cependant, PHP ne produit aucun résultat. 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/python2 et python2.7 au 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 alors que shutdown now ne fait rien.

PHP a les autorisations nécessaires pour accéder au fichier et l'exécuter.

EDIT: Merci à 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 fonctionne probablement pas/espérons-le en tant que root. Essayez de vous connecter en tant qu'utilisateur de votre serveur Web ou avec des autorisations similaires et essayez de lancer les commandes vous-même.

99

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

Dans PHP tilisez la fonction Shell_exec :

Exécutez la commande via 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 survient ou si la commande ne produit aucune sortie.

<?php 

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

?>

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

#!/usr/bin/env python

Aussi Python fichier doit avoir les privilèges appropriés (exécution pour l'utilisateur www-data/Apache si le script PHP s'exécute dans un navigateur ou une boucle) et/ou doit être " exécutable ". De même, toutes les commandes du fichier .py doivent avoir les privilèges appropriés:

Pris du manuel php :

Juste un rappel rapide pour ceux qui essaient d’utiliser Shell_exec sur une plate-forme de type Unix et ne semblent pas pouvoir 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 qu'il dispose des droits sur tous les fichiers ou répertoires que vous essayez d'utiliser dans la commande Shell_exec. Autrement, cela ne semblera rien faire.

Pour rendre exécutable un fichier sur des plateformes de type Unix :

chmod +x myscript.py
136
Alejandro Quiroz

Je recommande d'utiliser passthru et 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(); 
20
Niklas Lindblad

Si vous voulez connaître le statut de retour de la commande et obtenir la totalité de la sortie stdout, vous pouvez utiliser réellement exec:

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

$out est un tableau de toutes les lignes. $status est l'état de retour. Très utile pour le débogage.

Si vous souhaitez également voir la sortie stderr, vous pouvez jouer avec proc_open ou simplement ajouter 2>&1 à votre $command. Ce dernier est souvent suffisant pour que les choses fonctionnent et beaucoup plus rapidement pour "mettre en œuvre".

13
guaka

Alejandro a cloué le problème, ajoutant des précisions à 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

9
Colin Miles

Pour clarifier quelle commande utiliser en fonction de la situation

exec() - Exécuter un programme externe

system() - Exécuter un programme externe et afficher le résultat

passthru() - Exécuter un programme externe et afficher le résultat brut

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

5
Agnel Vishal

Dans mon cas, je devais créer un nouveau dossier dans le répertoire www appelé scripts. Dans scripts, j'ai ajouté un nouveau fichier appelé test.py.

J'ai ensuite utilisé Sudo chown www-data:root scripts et Sudo chown www-data:root test.py.

Ensuite, je suis allé dans le nouveau répertoire scripts et j'ai utilisé Sudo chmod +x test.py.

Mon fichier test.py ressemble à ceci. Notez la version Python différente:

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

De php je fais maintenant ceci:

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

Et vous devriez voir: Hello World!

3
Tim Hallman

Les méthodes ci-dessus semblent être 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 contenant un GO bouton. Chaque fois que vous appuierez sur ce bouton, un nouveau dossier sera 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");
2
Smshrimant

C'est si trivial, mais je voulais juste aider ceux qui suivaient déjà la suggestion d'Alejandro mais rencontraient cette erreur:

sh: blabla.py: commande non trouvée

Si quelqu'un rencontre cette erreur, un petit changement doit être apporté au fichier php par Alejandro:

$command = escapeshellcmd('python blabla.py');
1
Gerald Joshua