Esecuzione di uno script Python da PHP


114

Sto cercando di eseguire uno script Python da PHP utilizzando il seguente comando:

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

Tuttavia, PHP semplicemente non produce alcun output. La segnalazione degli errori è impostata su E_ALL e display_errors è attivo.

Ecco cosa ho provato:

  • Ho usato python2, /usr/bin/python2e python2.7invece di/usr/bin/python2.7
  • Ho anche usato un percorso relativo invece di un percorso assoluto che non ha cambiato nulla.
  • Ho provato utilizzando i comandi exec, shell_exec, system.

Tuttavia, se corro

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

funziona perfettamente bene mentre shutdown nownon fa nulla.

PHP dispone delle autorizzazioni per accedere ed eseguire il file.

EDIT: Grazie ad Alejandro, sono stato in grado di risolvere il problema. Se hai lo stesso problema, non dimenticare che il tuo server web probabilmente / si spera non funziona come root. Prova ad accedere come utente del tuo server web o come utente con autorizzazioni simili e prova a eseguire i comandi da solo.


Prima visita questo numero stackoverflow.com/questions/21659637/… Se non risolto e ottieni problemi come In Case se sei bloccato con le importazioni o tty o no askpass non funziona, controlla questo link per i dettagli sui passaggi per eseguirlo. stackoverflow.com/a/57978771/9470457 Grazie !!!
3rdi

Risposte:


159

Testato su Ubuntu Server 10.04. Spero che ti aiuti anche su Arch Linux.

In PHP usa la funzione shell_exec :

Esegui il comando tramite la shell e restituisci l'output completo come stringa.

Restituisce l'output del comando eseguito o NULL se si è verificato un errore o il comando non produce alcun output.

<?php 

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

?>

Nel file Python test.py, verifica questo testo nella prima riga: (vedi la spiegazione dello shebang) :

#!/usr/bin/env python

Anche il file Python deve avere i privilegi corretti (esecuzione per l'utente www-data / apache se lo script PHP viene eseguito nel browser o curl) e / o deve essere "eseguibile". Inoltre tutti i comandi nel .pyfile devono avere i privilegi corretti:

Tratto dal manuale php :

Solo un rapido promemoria per coloro che cercano di utilizzare shell_exec su una piattaforma di tipo unix e non riesco a farlo funzionare. PHP viene eseguito come utente Web sul sistema (generalmente www per Apache), quindi è necessario assicurarsi che l'utente Web abbia i diritti su qualsiasi file o directory che si sta tentando di utilizzare nel comando shell_exec. Altrimenti, sembra che non stia facendo nulla.

Per rendere eseguibile un file su piattaforme di tipo unix :

chmod +x myscript.py

6
Grazie, ha funzionato! C'era un altro problema: l'utente Apache non era in grado di eseguire un comando nello script Python, ma sono stato in grado di risolverlo usando sudo e aggiungendo un'eccezione per il mio script al file sudoers. Grazie ancora! :)
Account abbandonato il

1
Sto affrontando lo stesso problema dell'utente Apache, puoi guidarmi per favore?
Emma

1
ho usato la tua risposta, esegue bene lo script python ma non riesco a far eco ai risultati, niente appare nella pagina web, puoi aiutarmi.
Hamdi Charef

1
"#! / usr / bin / env python" sulla prima riga ha funzionato. Grande!
C3PO

1
Per OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); oppure:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
Cyborg

23

Consiglio di utilizzare passthrue gestire direttamente il buffer di output:

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

16

Se vuoi conoscere lo stato di ritorno del comando e ottenere l'intero stdoutoutput puoi effettivamente usare exec:

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

$outè un array di tutte le linee. $statusè lo stato del reso. Molto utile per il debug.

Se vuoi anche vedere l' stderroutput puoi giocare con proc_open o semplicemente aggiungerlo 2>&1al tuo file $command. Quest'ultimo è spesso sufficiente per far funzionare le cose e molto più velocemente da "implementare".


8

Alejandro lo ha inchiodato, aggiungendo chiarimenti all'eccezione (Ubuntu o Debian) - Non ho il rappresentante da aggiungere alla risposta stessa:

file sudoers: sudo visudo

eccezione aggiunta: www-data ALL=(ALL) NOPASSWD: ALL


7
Non sembra efficace aggiungere www-data a sudoer e fornisce ad apache più autorizzazioni di cui ha bisogno. Dare i permessi di www-data sullo script che stai eseguendo sarebbe sufficiente.
JasonRDalton

Bella idea, ma potrebbe sicuramente rendere vulnerabile il tuo sistema. Sono d'accordo con @JasonRDalton
Reed

6

Per chiarire quale comando utilizzare in base alla situazione

exec() - Eseguire un programma esterno

system() - Eseguire un programma esterno e visualizzare l'output

passthru() - Esegue un programma esterno e visualizza l'output grezzo

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


4

Nel mio caso avevo bisogno di creare una nuova cartella nella wwwdirectory chiamata scripts. All'interno scriptsho aggiunto un nuovo file chiamato test.py.

Ho quindi usato sudo chown www-data:root scriptse sudo chown www-data:root test.py.

Poi sono andato alla nuova scriptsdirectory e ho usato sudo chmod +x test.py.

Il mio file test.py assomiglia a questo. Nota la diversa versione di Python:

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

Da php ora faccio questo:

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

E dovresti vedere: Hello World!


3

I metodi di cui sopra sembrano essere complessi. Usa il mio metodo come riferimento.

Ho questi due file:

  • run.php

  • mkdir.py

Qui, ho creato una pagina HTML che contiene un GOpulsante. Ogni volta che si preme questo pulsante verrà creata una nuova cartella nella directory di cui si è indicato il percorso.

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

1

Questo è così banale, ma volevo solo aiutare chiunque avesse già seguito il suggerimento di Alejandro ma ha riscontrato questo errore:

sh: blabla.py: comando non trovato

Se qualcuno ha riscontrato questo errore, Alejandro deve apportare una piccola modifica al file php:

$command = escapeshellcmd('python blabla.py');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.