Executar um script Python a partir de PHP

114

Estou tentando executar um script Python em PHP usando o seguinte comando:

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

No entanto, o PHP simplesmente não produz nenhuma saída. O relatório de erros é definido como E_ALL e display_errors está ativado.

Aqui está o que tentei:

  • Eu usei python2, /usr/bin/python2e em python2.7vez de/usr/bin/python2.7
  • Também usei um caminho relativo em vez de um caminho absoluto, que também não mudou nada.
  • Eu tentei usar os comandos exec, shell_exec, system.

No entanto, se eu correr

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

funciona perfeitamente bem enquanto shutdown nownão faz nada.

O PHP tem permissão para acessar e executar o arquivo.

EDIT: Graças a Alejandro, consegui resolver o problema. Se você tiver o mesmo problema, não se esqueça que seu servidor da web provavelmente / espero que não execute como root. Tente fazer login como o usuário do seu servidor web ou um usuário com permissões semelhantes e tente executar os comandos você mesmo.

Conta abandonada
fonte
Primeiro, visite este problema stackoverflow.com/questions/21659637/… Se não for corrigido e você obter problemas como o In Case, se você ficar preso com as importações ou tty ou nenhum askpass funcionando, verifique este link para obter detalhes sobre as etapas para executá-lo. stackoverflow.com/a/57978771/9470457 Obrigado !!!
°

Respostas:

159

Testado no Ubuntu Server 10.04. Espero que ajude você também no Arch Linux.

Em PHP, use a função shell_exec :

Execute o comando via shell e retorne a saída completa como uma string.

Ele retorna a saída do comando executado ou NULL se ocorreu um erro ou o comando não produz saída.

<?php 

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

?>

No arquivo Python test.py, verifique este texto na primeira linha: (consulte a explicação do shebang) :

#!/usr/bin/env python

Além disso, o arquivo Python deve ter privilégios corretos (execução para o usuário www-data / apache se o script PHP for executado no navegador ou curl) e / ou deve ser "executável". Além disso, todos os comandos no .pyarquivo devem ter privilégios corretos:

Retirado do manual do php :

Apenas um lembrete rápido para aqueles que tentam usar shell_exec em uma plataforma do tipo Unix e não conseguem fazê-lo funcionar. O PHP é executado como o usuário da web no sistema (geralmente www para Apache), então você precisa ter certeza de que o usuário da web tem direitos para quaisquer arquivos ou diretórios que você está tentando usar no comando shell_exec. Caso contrário, não parecerá estar fazendo nada.

Para tornar um arquivo executável em plataformas do tipo Unix :

chmod +x myscript.py
Alejandro Quiroz
fonte
6
Obrigado, isso resolveu o problema! Havia mais um problema - o usuário Apache não foi capaz de executar um comando no script Python, mas eu consegui consertar isso usando sudo e adicionando uma exceção para meu script ao arquivo sudoers. Obrigado novamente! :)
Abandonada conta
1
Estou enfrentando o mesmo problema do usuário apache, você pode me orientar?
Emma
1
Usei sua resposta, ele executa o script python bem, mas não consigo exibir os resultados, nada aparece na página da web, você pode me ajudar.
Hamdi Charef de
1
"#! / usr / bin / env python" na primeira linha funcionou para mim. Ótimo!
C3PO
1
Para 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

Eu recomendo usar passthrue manipular o buffer de saída diretamente:

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

Se você deseja saber o status de retorno do comando e obter toda a stdoutsaída, pode realmente usar exec:

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

$outé uma matriz de todas as linhas. $statusé o status de retorno. Muito útil para depuração.

Se você também quiser ver a stderrsaída, pode brincar com proc_open ou simplesmente adicionar 2>&1ao seu $command. O último geralmente é suficiente para fazer as coisas funcionarem e muito mais rápido para "implementar".

kqw
fonte
8

Alejandro acertou em cheio, acrescentando um esclarecimento à exceção (Ubuntu ou Debian) - não tenho o representante para acrescentar à própria resposta:

arquivo sudoers: sudo visudo

exceção adicionada: www-data ALL=(ALL) NOPASSWD: ALL

Colin Miles
fonte
7
Não parece eficaz adicionar www-data a sudoers e dá ao apache mais permissões de que precisa. Dar permissões www-data no script que você está executando seria suficiente.
JasonRDalton
Boa ideia, mas pode definitivamente tornar seu sistema vulnerável. Eu concordo com @JasonRDalton
Reed
6

Para esclarecer qual comando usar com base na situação

exec() - Executar um programa externo

system() - Executar um programa externo e exibir a saída

passthru() - Executar um programa externo e exibir a saída bruta

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

Agnel Vishal
fonte
4

No meu caso precisei criar uma nova pasta no wwwdiretório chamado scripts. Dentro scriptseu adicionei um novo arquivo chamado test.py.

Então usei sudo chown www-data:root scriptse sudo chown www-data:root test.py.

Então fui para o novo scriptsdiretório e usei sudo chmod +x test.py.

Meu arquivo test.py se parece com isso. Observe a versão diferente do Python:

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

No php, agora faço o seguinte:

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

E você deverá ver: Hello World!

Tim Hallman
fonte
3

Os métodos acima parecem complexos. Use meu método como referência.

Eu tenho estes dois arquivos:

  • run.php

  • mkdir.py

Aqui, criei uma página HTML que contém um GObotão. Sempre que você pressionar este botão, uma nova pasta será criada no diretório cujo caminho você mencionou.

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
fonte
1

Isso é tão trivial, mas só queria ajudar quem já seguiu a sugestão de Alejandro, mas encontrou este erro:

sh: blabla.py: comando não encontrado

Se alguém encontrou esse erro, uma pequena alteração precisa ser feita no arquivo php por Alejandro:

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