เรียกใช้สคริปต์ Python จาก PHP


114

ฉันพยายามเรียกใช้สคริปต์ Python จาก PHP โดยใช้คำสั่งต่อไปนี้:

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

อย่างไรก็ตาม PHP ไม่ได้สร้างผลลัพธ์ใด ๆ การรายงานข้อผิดพลาดถูกตั้งค่าเป็น E_ALL และ display_errors เปิดอยู่

นี่คือสิ่งที่ฉันได้ลอง:

  • ผมใช้python2, /usr/bin/python2และpython2.7แทน/usr/bin/python2.7
  • ฉันยังใช้เส้นทางสัมพัทธ์แทนเส้นทางสัมบูรณ์ซึ่งไม่ได้เปลี่ยนแปลงอะไรเลย
  • ฉันพยายามใช้คำสั่งexec, ,shell_execsystem

อย่างไรก็ตามหากฉันวิ่ง

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

มันทำงานได้ดีอย่างสมบูรณ์ในขณะที่shutdown nowไม่ได้ทำอะไรเลย

PHP มีสิทธิ์ในการเข้าถึงและเรียกใช้ไฟล์

แก้ไข: ขอบคุณ Alejandro ฉันสามารถแก้ไขปัญหาได้ หากคุณมีปัญหาเดียวกันอย่าลืมว่าเว็บเซิร์ฟเวอร์ของคุณอาจ / หวังว่าจะไม่ทำงานในฐานะรูท ลองเข้าสู่ระบบในฐานะผู้ใช้เว็บเซิร์ฟเวอร์ของคุณหรือผู้ใช้ที่มีสิทธิ์คล้ายกันแล้วลองรันคำสั่งด้วยตัวเอง


ขั้นแรกให้ไปที่ปัญหานี้stackoverflow.com/questions/21659637/…หากไม่ได้รับการแก้ไขและคุณพบปัญหาเช่นในกรณีที่คุณติดอยู่กับการนำเข้าหรือ tty หรือไม่มี askpass ไม่ทำงานโปรดตรวจสอบลิงค์นี้เพื่อดูขั้นตอนรายละเอียดในการดำเนินการ stackoverflow.com/a/57978771/9470457ขอบคุณครับ !!!
3

คำตอบ:


159

ทดสอบบน Ubuntu Server 10.04 ฉันหวังว่ามันจะช่วยคุณใน Arch Linux

ใน PHP ใช้ฟังก์ชัน shell_exec :

ดำเนินการคำสั่งผ่านเชลล์และส่งคืนผลลัพธ์ที่สมบูรณ์เป็นสตริง

ส่งคืนเอาต์พุตจากคำสั่งที่เรียกใช้งานหรือ NULL หากเกิดข้อผิดพลาดหรือคำสั่งไม่สร้างเอาต์พุต

<?php 

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

?>

ในไฟล์ Python test.pyให้ตรวจสอบข้อความนี้ในบรรทัดแรก: (ดูคำอธิบายของ shebang) :

#!/usr/bin/env python

นอกจากนี้ไฟล์ Python ต้องมีสิทธิ์ที่ถูกต้อง (การเรียกใช้ www-data / apache ของผู้ใช้หากสคริปต์ PHP ทำงานในเบราว์เซอร์หรือ curl) และ / หรือต้องเป็น "ปฏิบัติการ" คำสั่งทั้งหมดใน.pyไฟล์ต้องมีสิทธิ์ที่ถูกต้อง:

นำมาจากคู่มือ php :

ขอเตือนเพียงสั้น ๆ สำหรับผู้ที่พยายามใช้ shell_exec บนแพลตฟอร์มแบบยูนิกซ์และดูเหมือนจะไม่สามารถใช้งานได้ PHP ดำเนินการในฐานะผู้ใช้เว็บในระบบ (โดยทั่วไปคือ www สำหรับ Apache) ดังนั้นคุณต้องตรวจสอบให้แน่ใจว่าผู้ใช้เว็บมีสิทธิ์ในไฟล์หรือไดเรกทอรีใด ๆ ที่คุณพยายามใช้ในคำสั่ง shell_exec ฉลาดอื่น ๆ ดูเหมือนจะไม่ทำอะไรเลย

ในการทำให้ไฟล์ปฏิบัติการได้บนแพลตฟอร์มประเภทยูนิกซ์ :

chmod +x myscript.py

6
ขอบคุณที่ทำเคล็ดลับ! มีปัญหาอีกอย่างหนึ่ง - ผู้ใช้ Apache ไม่สามารถรันคำสั่งในสคริปต์ Python ได้ แต่ฉันสามารถแก้ไขได้โดยใช้ sudo และเพิ่มข้อยกเว้นสำหรับสคริปต์ของฉันลงในไฟล์ sudoers ขอบคุณอีกครั้ง! :)
บัญชีที่ถูกละทิ้ง

1
ฉันประสบปัญหาเดียวกันกับผู้ใช้ apache คุณช่วยแนะนำฉันได้ไหม
Emma

1
ฉันใช้คำตอบของคุณมันรันสคริปต์ python ได้ดี แต่ฉันไม่สามารถสะท้อนผลลัพธ์ที่ไม่ปรากฏในหน้าเว็บได้คุณช่วยฉันได้ไหม
Hamdi Charef

1
"#! / usr / bin / env python" ในบรรทัดแรกหลอกฉัน ที่ดี!
C3PO

1
สำหรับOSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py");หรือ:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
Cyborg

24

ฉันขอแนะนำให้ใช้passthruและจัดการบัฟเฟอร์เอาต์พุตโดยตรง:

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

16

หากคุณต้องการทราบสถานะการส่งคืนของคำสั่งและรับstdoutผลลัพธ์ทั้งหมดที่คุณสามารถใช้ได้จริงexec:

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

$outคืออาร์เรย์ของทุกบรรทัด $statusคือสถานะการคืนสินค้า มีประโยชน์มากสำหรับการดีบัก

หากคุณต้องการดูstderrผลลัพธ์คุณสามารถเล่นกับproc_openหรือเพิ่มลง2>&1ใน$commandไฟล์. อย่างหลังมักจะเพียงพอที่จะทำให้สิ่งต่างๆทำงานได้ดีและเร็วขึ้นในการ "นำไปใช้"


8

Alejandro ตอกมันเพิ่มคำชี้แจงให้กับข้อยกเว้น (Ubuntu หรือ Debian) - ฉันไม่มีตัวแทนที่จะเพิ่มคำตอบเอง:

ไฟล์ sudoers: sudo visudo

เพิ่มข้อยกเว้น: www-data ALL=(ALL) NOPASSWD: ALL


7
ดูเหมือนจะไม่มีประสิทธิภาพในการเพิ่ม www-data ไปยัง sudoers และให้สิทธิ์ apache มากขึ้นตามที่ต้องการ การให้สิทธิ์ www-data ในสคริปต์ที่คุณกำลังเรียกใช้ก็เพียงพอแล้ว
JasonRDalton

ไอเดียเจ๋ง แต่อาจทำให้ระบบของคุณมีช่องโหว่ได้ ฉันเห็นด้วยกับ @JasonRDalton
Reed

6

เพื่อชี้แจงว่าจะใช้คำสั่งใดตามสถานการณ์

exec() - รันโปรแกรมภายนอก

system() - รันโปรแกรมภายนอกและแสดงผลลัพธ์

passthru() - รันโปรแกรมภายนอกและแสดงเอาต์พุตดิบ

ที่มา: http://php.net/manual/en/function.exec.php


4

ในกรณีของฉันฉันต้องสร้างโฟลเดอร์ใหม่ในwwwไดเร็กทอรีชื่อscripts. ภายในscriptsฉันได้เพิ่มไฟล์ใหม่ชื่อtest.py .

ฉันใช้แล้วsudo chown www-data:root scriptsและsudo chown www-data:root test.pyและ

จากนั้นฉันไปที่scriptsไดเร็กทอรีใหม่และใช้sudo chmod +x test.pyไดเรกทอรีและใช้

ไฟล์ test.py ของฉันมีลักษณะเช่นนี้ สังเกตเวอร์ชัน Python ที่แตกต่างกัน:

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

จาก php ตอนนี้ฉันทำสิ่งนี้:

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

และคุณควรเห็น: Hello World!


3

วิธีการข้างต้นดูเหมือนจะซับซ้อน ใช้วิธีของฉันเป็นข้อมูลอ้างอิง

ฉันมีสองไฟล์นี้:

  • run.php

  • mkdir.py

ที่นี่ฉันได้สร้างหน้า HTML ซึ่งมีไฟล์ GOปุ่ม เมื่อใดก็ตามที่คุณกดปุ่มนี้โฟลเดอร์ใหม่จะถูกสร้างขึ้นในไดเร็กทอรีที่มีพา ธ ที่คุณกล่าวถึง

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

นี่เป็นเรื่องเล็กน้อย แต่ต้องการช่วยทุกคนที่ทำตามคำแนะนำของ Alejandro แล้ว แต่พบข้อผิดพลาดนี้:

sh: blabla.py: ไม่พบคำสั่ง

หากใครพบข้อผิดพลาดนั้นจำเป็นต้องทำการเปลี่ยนแปลงเล็กน้อยกับไฟล์ php โดย Alejandro:

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

0

แรงบันดาลใจจาก Alejandro Quiroz:

<?php 

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

?>

ต้องเพิ่ม Python และไม่ต้องการเส้นทาง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.