Ejecutar un script de Python desde PHP

114

Estoy tratando de ejecutar un script de Python desde PHP usando el siguiente comando:

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

Sin embargo, PHP simplemente no produce ningún resultado. El informe de errores se establece en E_ALL y display_errors está activado.

Esto es lo que probé:

  • Usé python2, /usr/bin/python2y en python2.7lugar de/usr/bin/python2.7
  • También utilicé una ruta relativa en lugar de una ruta absoluta que tampoco cambió nada.
  • He intentado utilizar los comandos exec, shell_exec, system.

Sin embargo, si corro

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

funciona perfectamente bien mientras shutdown nowno hace nada.

PHP tiene los permisos para acceder y ejecutar el archivo.

EDITAR: Gracias a Alejandro, pude solucionar el problema. Si tiene el mismo problema, no olvide que su servidor web probablemente / con suerte no se ejecute como root. Intente iniciar sesión como usuario de su servidor web o un usuario con permisos similares e intente ejecutar los comandos usted mismo.

Cuenta abandonada
fuente
Primero, visite este problema stackoverflow.com/questions/21659637/… Si no se solucionó y tiene problemas como En caso de que se quede atascado con las importaciones o tty o no, askpass no funciona, consulte este enlace para obtener detalles sobre los pasos para ejecutarlo. stackoverflow.com/a/57978771/9470457 ¡¡¡Gracias !!!
3 de

Respuestas:

159

Probado en Ubuntu Server 10.04. Espero que te ayude también en Arch Linux.

En PHP use la función shell_exec :

Ejecute el comando a través del shell y devuelva la salida completa como una cadena.

Devuelve la salida del comando ejecutado o NULL si ocurrió un error o el comando no produce salida.

<?php 

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

?>

En el archivo Python test.py, verifique este texto en la primera línea: (vea la explicación de shebang) :

#!/usr/bin/env python

Además, el archivo Python debe tener los privilegios correctos (ejecución para el usuario www-data / apache si el script PHP se ejecuta en el navegador o curl) y / o debe ser "ejecutable". Además, todos los comandos en el .pyarchivo deben tener los privilegios correctos:

Tomado del manual de php :

Solo un recordatorio rápido para aquellos que intentan usar shell_exec en una plataforma de tipo Unix y parece que no pueden hacer que funcione. PHP se ejecuta como el usuario web en el sistema (generalmente www para Apache), por lo que debe asegurarse de que el usuario web tenga derechos sobre los archivos o directorios que esté intentando utilizar en el comando shell_exec. De lo contrario, no parecerá estar haciendo nada.

Para convertir un archivo en ejecutable en plataformas de tipo Unix :

chmod +x myscript.py
Alejandro Quiroz
fuente
6
¡Gracias, eso funcionó! Hubo un problema más: el usuario de Apache no pudo ejecutar un comando en el script de Python, pero pude solucionarlo usando sudo y agregando una excepción para mi script al archivo sudoers. ¡Gracias de nuevo! :)
Cuenta abandonada el
1
Estoy enfrentando el mismo problema del usuario de apache, ¿pueden guiarme?
Emma
1
Usé su respuesta, ejecutó bien el script de Python pero no puedo repetir los resultados, nada aparece en la página web, ¿pueden ayudarme?
Hamdi Charef
1
"#! / usr / bin / env python" en la primera línea me hizo el truco. ¡Excelente!
C3PO
1
Para OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); o:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
Cyborg
23

Recomiendo usar passthruy manejar el búfer de salida directamente:

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

Si desea conocer el estado de retorno del comando y obtener el stdoutresultado completo , puede usar exec:

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

$outes una matriz de todas las líneas. $statuses el estado de devolución. Muy útil para depurar.

Si también desea ver la stderrsalida, puede jugar con proc_open o simplemente agregar 2>&1a su archivo$command . Esto último suele ser suficiente para que las cosas funcionen y mucho más rápido de "implementar".

kqw
fuente
8

Alejandro lo clavó, agregando una aclaración a la excepción (Ubuntu o Debian): no tengo el representante para agregar a la respuesta en sí:

archivo sudoers: sudo visudo

excepción agregada: www-data ALL=(ALL) NOPASSWD: ALL

Colin Miles
fuente
7
No parece efectivo agregar www-data a los sudoers y le otorga a apache más permisos de los que necesita. Dar permisos de www-data en el script que está ejecutando sería suficiente.
JasonRDalton
Buena idea, pero definitivamente podría hacer que su sistema sea vulnerable. Estoy de acuerdo con @JasonRDalton
Reed
6

Para aclarar qué comando usar según la situación

exec() - Ejecutar un programa externo

system() - Ejecutar un programa externo y mostrar la salida

passthru() - Ejecutar un programa externo y mostrar la salida sin procesar

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

Agnel Vishal
fuente
4

En mi caso, necesitaba crear una nueva carpeta en el wwwdirectorio llamado scripts. Dentro scriptsagregué un nuevo archivo llamado test.py.

Luego usé sudo chown www-data:root scriptsy sudo chown www-data:root test.py.

Luego fui al nuevo scriptsdirectorio y usé sudo chmod +x test.py.

Mi archivo test.py se ve así. Tenga en cuenta la versión diferente de Python:

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

Desde php ahora hago esto:

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

Y debería ver: ¡Hola mundo!

Tim Hallman
fuente
3

Los métodos anteriores parecen ser complejos. Usa mi método como referencia.

Tengo estos dos archivos:

  • ejecutar.php

  • mkdir.py

Aquí, he creado una página HTML que contiene un GObotón. Siempre que presione este botón se creará una nueva carpeta en el directorio cuya ruta ha mencionado.

ejecutar.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
fuente
1

Esto es tan trivial, pero solo quería ayudar a cualquiera que ya haya seguido la sugerencia de Alejandro pero haya encontrado este error:

sh: blabla.py: comando no encontrado

Si alguien encuentra ese error, entonces Alejandro debe hacer un pequeño cambio en el archivo php:

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