Ejecutando un script Python desde PHP

Estoy tratando de ejecutar un script 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 ninguna salida. El reporte de error se establece en E_ALL y display_errors está encendido.

Esto es lo que he intentado:

  • Yo solía. python2, /usr/bin/python2 y python2.7 en lugar de /usr/bin/python2.7
  • También usé un camino relativo en lugar de un camino absoluto que tampoco cambió nada.
  • Traté de usar los comandos exec, shell_exec, system.

Sin embargo, si corro

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

funciona perfectamente bien shutdown now no hace nada.

PHP tiene los permisos para acceder y ejecutar el archivo.

EDIT: Gracias a Alejandro, pude solucionar el problema. Si tienes el mismo problema, no olvides que tu servidor web probablemente/esperadamente no funciona 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.

Pregunta hecha hace 10 años, 3 meses, 24 días - Por scriptwarrior


11 Respuestas:

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

    En PHP use shell_exec function:

    Ejecutar el comando vía shell y devolver la salida completa como una cadena.

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

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

    Into Python file test.py, verifique este texto en primera línea: (ver Shebang explicar):

    #!/usr/bin/env python
    

    Si tiene varias versiones de Python instalado, /usr/bin/env asegurar que el intérprete utilizado es el primero en su entorno Por Dios. La alternativa sería codificar algo como #!/usr/bin/python; eso está bien, pero menos flexible.

    En Unix, un archivo ejecutable que debe ser interpretado puede indicar qué intérprete utilizar por tener un #! al comienzo de la primera línea, seguido por el intérprete (y cualquier bandera que necesite).

    Si estás hablando de otras plataformas, por supuesto, esta regla no aplicar (pero esa "línea de la banca" no hace daño, y ayudará si alguna vez copiar ese script a una plataforma con una base Unix, como Linux, Mac, etc.

    Esto se aplica cuando se ejecuta en Unix por hacerlo ejecutable (chmod +x myscript.py) y luego ejecutarlo directamente: ./myscript.py, en lugar de pitón miscript. py

    A hacer ejecutable un archivo en plataformas de tipo unix:

    chmod +x myscript.py
    

    También archivo Python debe tener privilegios correctos (ejecución para el usuario www-data / apache si PHP script se ejecuta en el navegador o curl) y/o debe ser "ejecutable". También todos los comandos en .py archivo debe tener privilegios correctos.

    Taken del manual de php:

    Sólo un recordatorio rápido para aquellos que intentan usar shell_exec en un plataforma de tipo unix y no parece conseguir que funcione. PHP ejecuta como el usuario web en el sistema (generalmente www para Apache), por lo que necesita asegúrese de que el usuario web tiene derechos a cualquier archivo o directorios que está intentando utilizar en el comando shell_exec. Otros sabios, no parecerá estar haciendo nada.

    Respondida el Nov 01, 2013 a las 21:02 - por debugdynamo46a0

    Votos positivos: 0 | Votos negativos: 0

  • Recomiendo usar passthru y el manejo del buffer de salida directamente:

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

    Respondida el Nov 01, 2013 a las 21:09 - por coderconqueror

    Votos positivos: 0 | Votos negativos: 0

  • Si desea conocer el estado de retorno del comando y obtener todo stdout salida puede en realidad exec:

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

    $out es una variedad de todas las líneas. $status es el estado de retorno. Muy útil para depurar.

    Si también quieres ver el stderr salida que puede jugar con proc_open o simplemente añadir 2>&1 a su $command. Este último es a menudo suficiente para hacer que las cosas funcionen y mucho más rápido para "ejecutar".

    Respondida el Nov 01, 2013 a las 21:15 - por cybermage

    Votos positivos: 0 | Votos negativos: 0

  • Para aclarar qué comando utilizar basado en la situación

    exec() - Ejecutar un programa externo

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

    passthru() - Ejecutar un programa externo y mostrar salida cruda

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

    Respondida el Nov 01, 2013 a las 21:20 - por pixelpioneerbbb5

    Votos positivos: 0 | Votos negativos: 0

  • Alejandro lo enganchó, añadiendo aclaración a la excepción (Ubuntu o Debian) - No tengo la reputación de añadir a la respuesta misma:

    sudoers file: sudo visudo

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

    Respondida el Nov 01, 2013 a las 21:29 - por compilerchieftain

    Votos positivos: 0 | Votos negativos: 0

  • En mi caso necesitaba crear una nueva carpeta en la www directorio llamado scripts. Dentro scripts He añadido un nuevo archivo llamado test.py.

    Entonces usé sudo chown www-data:root scripts y sudo chown www-data:root test.py.

    Luego fui al nuevo scripts directorio y uso sudo chmod +x test.py.

    Mi prueba. Py file se ve así. Note la versión diferente de Python:

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

    De Php ahora hago esto:

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

    Y deberías ver: ¡Hola Mundo!

    Respondida el Nov 01, 2013 a las 21:39 - por syntaxsensei8acf

    Votos positivos: 0 | Votos negativos: 0

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

    Tengo estos dos archivos:

    • Corre.

    • mkdir.py

    He creado una página HTML que contiene una Vamos. Botón. Cada vez que pulsa este botón se creará una nueva carpeta en el directorio cuyo camino ha mencionado.

    Corre.

    
     
      
       
         run
       
      
    
       
    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");
    

    Respondida el Nov 01, 2013 a las 21:49 - por pixelpioneerbbb5

    Votos positivos: 0 | Votos negativos: 0

  • Inspirado por Alejandro Quiroz:

    php 
    
    $command = escapeshellcmd('python test.py');
    $output = shell_exec($command);
    echo $output;
    
    ?
    

    Necesito añadir Python, y no necesito el camino.

    Respondida el Nov 01, 2013 a las 21:55 - por javagiant

    Votos positivos: 0 | Votos negativos: 0

  • Todas las opciones anteriores crean un nuevo proceso de sistema. Lo cual es una pesadilla de rendimiento. Para este propósito cosí un módulo PHP con llamadas "transparentes" a Python.

    https://github.com/kirmorozov/runpy

    Puede ser difícil de compilar, pero guardará los procesos del sistema y le permitirá mantener el tiempo de ejecución de Python entre las llamadas PHP.

    Respondida el Nov 01, 2013 a las 22:05 - por syntaxsensei8acf

    Votos positivos: 0 | Votos negativos: 0

  • Me alegra escuchar que pudiste solucionar tu problema y que mis sugerencias fueron de ayuda. Es importante recordar que a menudo los problemas de ejecución de comandos desde PHP a través de exec, shell_exec o system pueden estar relacionados con permisos de usuario y de directorio.

    Si en el pasado hubo dificultades para ejecutar el script Python desde PHP, ten en cuenta que, cuando PHP se ejecuta a través del servidor web, generalmente tiene permisos limitados, por lo que es posible que necesites ajustar los permisos de los archivos y directorios relevantes para que el servidor web pueda acceder y ejecutar el script Python correctamente.

    Si vuelves a encontrarte con problemas similares en el futuro, asegúrate de verificar los permisos de los archivos, el usuario bajo el cual se está ejecutando el servidor web y cualquier configuración de seguridad que pueda estar interfiriendo con la ejecución de scripts externos desde PHP. ¡Espero que esta información sea útil para tus futuros proyectos!

    Respondida el Nov 02, 2013 a las 21:02 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Solución:

    El problema probablemente se deba a que el servidor web no se ejecuta como usuario root. Cuando intentas ejecutar el comando exec, este se ejecuta con los permisos del servidor web, que es un usuario diferente.

    Para resolver este problema, intenta iniciar sesión como el usuario del servidor web o un usuario con permisos similares y ejecutar el comando manualmente. Esto te ayudará a determinar si el problema está relacionado con los permisos o con la configuración del servidor web.

    Alternativamente, puedes intentar:

    Especificar la ruta completa al intérprete de Python, incluyendo el nombre del archivo ejecutable (por ejemplo, /usr/bin/python). Usar el comando passthru en lugar de exec para que la salida del script de Python se imprima directamente en el navegador. Asegurarte de que el script de Python tenga los permisos de ejecución correctos. Verificar que el servidor web tenga permiso para acceder y ejecutar el script de Python.

    Ejemplo:

    php
    
    

    Respondida el Nov 02, 2013 a las 21:05 - por Gemini

    Votos positivos: 0 | Votos negativos: 0