Menjalankan skrip Python dari PHP

114

Saya mencoba menjalankan skrip Python dari PHP menggunakan perintah berikut:

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

Namun, PHP tidak menghasilkan keluaran apa pun. Pelaporan kesalahan disetel ke E_ALL dan display_errors aktif.

Inilah yang saya coba:

  • Saya menggunakan python2, /usr/bin/python2dan python2.7sebagai gantinya/usr/bin/python2.7
  • Saya juga menggunakan jalur relatif alih-alih jalur absolut yang juga tidak mengubah apa pun.
  • Saya mencoba menggunakan perintah exec, shell_exec, system.

Namun, jika saya lari

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

itu bekerja dengan baik sementara shutdown nowtidak melakukan apapun.

PHP memiliki izin untuk mengakses dan mengeksekusi file.

EDIT: Terima kasih kepada Alejandro, saya bisa memperbaiki masalah. Jika Anda mengalami masalah yang sama, jangan lupa bahwa server web Anda mungkin / mudah-mudahan tidak berjalan sebagai root. Coba masuk sebagai pengguna server web Anda atau pengguna dengan izin serupa dan coba jalankan perintah sendiri.

Akun yang ditinggalkan
sumber
Pertama Kunjungi masalah ini stackoverflow.com/questions/21659637/… Jika tidak diperbaiki dan Anda mendapatkan masalah seperti Seandainya jika Anda terjebak dengan impor atau tty atau tidak ada askpass yang tidak berfungsi, silakan periksa tautan ini untuk mengetahui detail langkah-langkah untuk menjalankannya. stackoverflow.com/a/57978771/9470457 Terima kasih !!!
3rdi

Jawaban:

159

Diuji di Ubuntu Server 10.04. Saya harap ini juga membantu Anda di Arch Linux.

Dalam PHP gunakan fungsi shell_exec :

Jalankan perintah melalui shell dan kembalikan keluaran lengkap sebagai string.

Ini mengembalikan output dari perintah yang dieksekusi atau NULL jika terjadi kesalahan atau perintah tidak menghasilkan output.

<?php 

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

?>

Dalam file Python test.py, verifikasi teks ini di baris pertama: (lihat shebang menjelaskan) :

#!/usr/bin/env python

Juga file Python harus memiliki hak yang benar (eksekusi untuk pengguna www-data / apache jika skrip PHP berjalan di browser atau curl) dan / atau harus "dapat dieksekusi". Juga semua perintah ke dalam .pyfile harus memiliki hak istimewa yang benar:

Diambil dari manual php :

Hanya pengingat cepat bagi mereka yang mencoba menggunakan shell_exec pada platform tipe unix dan sepertinya tidak dapat membuatnya berfungsi. PHP dijalankan sebagai pengguna web pada sistem (umumnya www untuk Apache), jadi Anda perlu memastikan bahwa pengguna web memiliki hak atas file atau direktori apa pun yang Anda coba gunakan dalam perintah shell_exec. Jika tidak, tampaknya tidak akan melakukan apa pun.

Untuk membuat file yang dapat dieksekusi pada platform tipe unix :

chmod +x myscript.py
Alejandro Quiroz
sumber
6
Terima kasih, itu berhasil! Ada satu masalah lagi - pengguna Apache tidak dapat menjalankan perintah dalam skrip Python tetapi saya dapat memperbaikinya dengan menggunakan sudo dan menambahkan pengecualian untuk skrip saya ke file sudoers. Terima kasih lagi! :)
Akun yang
1
Saya menghadapi masalah yang sama dengan pengguna apache, dapatkah Anda membimbing saya?
Emma
1
Saya menggunakan jawaban Anda, itu mengeksekusi skrip python dengan baik tetapi saya tidak dapat menggemakan hasil tidak ada yang muncul di halaman web, dapatkah Anda membantu saya.
Hamdi Charef
1
"#! / usr / bin / env python" pada baris pertama melakukan trik bagi saya. Bagus!
C3PO
1
Untuk OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); atau:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
Cyborg
23

Saya merekomendasikan menggunakan passthrudan menangani buffer keluaran secara langsung:

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

Jika Anda ingin mengetahui status kembalian dari perintah dan mendapatkan seluruh stdoutoutput, Anda sebenarnya dapat menggunakan exec:

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

$outadalah larik dari semua baris. $statusadalah status pengembalian. Sangat berguna untuk debugging.

Jika Anda juga ingin melihat stderrhasilnya, Anda dapat bermain dengan proc_open atau menambahkannya 2>&1ke file $command. Yang terakhir ini seringkali cukup untuk membuat segala sesuatunya bekerja dan cara yang lebih cepat untuk "diimplementasikan".

kqw
sumber
8

Alejandro berhasil, menambahkan klarifikasi ke pengecualian (Ubuntu atau Debian) - Saya tidak memiliki perwakilan untuk menambahkan jawaban itu sendiri:

file sudoers: sudo visudo

pengecualian ditambahkan: www-data ALL=(ALL) NOPASSWD: ALL

Colin Miles
sumber
7
Tampaknya tidak efektif untuk menambahkan www-data ke sudoers, dan memberikan apache lebih banyak izin yang dibutuhkannya. Memberikan izin www-data pada skrip yang Anda jalankan sudah cukup.
JasonRDalton
Ide keren, tapi pasti bisa membuat sistem Anda rentan. Saya setuju dengan @JasonRDD
Reed
6

Untuk memperjelas perintah mana yang akan digunakan berdasarkan situasi

exec() - Jalankan program eksternal

system() - Jalankan program eksternal dan tampilkan hasilnya

passthru() - Jalankan program eksternal dan tampilkan keluaran mentah

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

Agnel Vishal
sumber
4

Dalam kasus saya, saya perlu membuat folder baru di wwwdirektori bernama scripts. Di dalam scriptssaya menambahkan file baru bernama test.py.

Saya kemudian menggunakan sudo chown www-data:root scriptsdan sudo chown www-data:root test.py.

Lalu saya pergi ke scriptsdirektori baru dan menggunakan sudo chmod +x test.py.

File test.py saya terlihat seperti ini. Perhatikan versi Python yang berbeda:

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

Dari php saya sekarang melakukan ini:

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

Dan Anda akan melihat: Halo Dunia!

Tim Hallman
sumber
3

Metode di atas sepertinya rumit. Gunakan metode saya sebagai referensi.

Saya memiliki dua file ini:

  • run.php

  • mkdir.py

Di sini, saya telah membuat halaman HTML yang berisi GOtombol. Setiap kali Anda menekan tombol ini, folder baru akan dibuat di direktori yang jalurnya telah Anda sebutkan.

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

Ini sangat sepele, tetapi hanya ingin membantu siapa saja yang telah mengikuti saran Alejandro tetapi mengalami kesalahan ini:

sh: blabla.py: perintah tidak ditemukan

Jika ada yang mengalami kesalahan itu, maka sedikit perubahan perlu dilakukan pada file php oleh Alejandro:

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