2009-02-19 42 views
15

Tôi đang cố gắng gọi một tập lệnh mất vài giây (dịch vụ web với bên thứ ba) bằng cách sử dụng lệnh gọi hàm exec PHP. Sau nhiều khó khăn, tôi đã giảm điều này thành ví dụ thế giới hello cổ điển. Các kịch bản gọi trông giống như:Không thể thực thi tập lệnh PHP bằng cách sử dụng PHP exec

exec('/usr/bin/php /home/quote2bi/tmp/helloworld.php > /tmp/execoutput.txt 2>&1 &'); 

Khi tôi chạy này, sản lượng execoutput.txt chứa một bản sao của trang cách gọi kịch bản, không hello world như tôi mong đợi.

Tại sao tôi không thể lấy tập lệnh PHP này để thực thi bằng lệnh exec? Lưu ý rằng khi tôi thay đổi lệnh thành một cái gì đó như ls -l, đầu ra là một danh sách thư mục như mong đợi. btw, trong trường hợp nó quan trọng, tôi đã chmod kịch bản được gọi là 755 ...

Cập nhật - Tôi đã chuyển cuộc gọi exec đến cuối tập lệnh gọi và ít nhất giờ tôi không thấy tập lệnh gọi được thực hiện trong đầu ra. Thx để áp phích và tôi sẽ thử một số trong những ý tưởng này.

Trợ giúp!

Cảm ơn Steve

Trả lời

16

exec gì đang làm là lấy lệnh ngoài cùng bên phải và phụ nó đến đích của bạn. Nếu bạn có dòng shebang trong tập lệnh php của mình, bạn không cần phải bao gồm chỉ thị nhị phân của trình thông dịch php.

nếu bạn chỉ muốn đầu ra của kịch bản, hãy thử:

exec('/home/quote2bi/tmp/helloworld.php > /tmp/execoutput.txt 2>&1 &') 

tuy nhiên nếu bạn không muốn các lỗi là trong file, bạn nên chuyển hướng thiết bị lỗi chuẩn trước khi xuất ra đến tập tin. Giống như vậy:

exec('/home/quote2bi/tmp/helloworld.php 2> /dev/null > /tmp/execoutput.txt') 

ở trên chỉ nên xuất ra "Hello World" đến lệnh thực thi.

Edit:

Thú vị bạn đang nhận được hành vi này. Bạn đã nói lệnh "ls" đã hoạt động. Hãy thử làm một bí danh cho điều này và chuyển nó vào một tập tin như vậy:

alias pexec='php /home/quote2bi/tmp/helloworld.php'

sau đó

exec('pexec > /tmp/execoutput.txt 2>&1 &') 

nó có vẻ là một vấn đề với cách exec xử lý đầu vào như trái ngược với vỏ thân .

-John

+1

John - cảm ơn câu trả lời của bạn, nhưng thật không may, nó không hiệu quả với tôi. Khi tôi thử: exec ('/ home/quote2bi/tmp/helloworld.php> /tmp/execoutput.txt 2> & 1 &') ... Tôi nhận được kết quả tương tự (trang hiện tại trong tệp đầu ra). Các exec thứ hai bị chặn (thiếu &) - khi thêm tôi đã nhận được kết quả tương tự. –

+0

Có tùy chọn nào nếu chức năng exec() bị vô hiệu hóa trên máy chủ của tôi –

7

Vấn đề là với chính PHP, nó xử lý mọi thứ như $ argv trong tập lệnh. Nó không chuyển hướng đầu ra sang tệp tin ou tới/dev/null.

Tôi đã gặp phải vấn đề tương tự một thời gian trước đây. Những gì tôi đã làm là để tạo ra một runscript.php trong/opt/php-bin và sau đó bên trong kịch bản này chạy những gì nó cần được chạy.Một cái gì đó như thế này:

$script = $argv[1] 
$params = implode(' ', array_slice($argv, 2)); 
$cmd = "{$script} {$params} > /dev/null &"; 

$output = array(); 
$return = 0; 
exec("php {$cmd}", $output, $return); 

exit((int)$return); 

Và sau đó bạn gọi nó là sử dụng:

exec('/opt/php-bin/runscript.php /path/to/your/script.php arg1 arg2') 

Nó rất cách duy nhất tôi quản lý để làm việc này.

0

Để tránh các vấn đề đã nêu của PHP trong khu vực này, tại sao không đặt vấn đề này vào bên trong một kịch bản lệnh shell? PHP sau đó có thể thực thi kịch bản lệnh shell có tất cả các chuyển hướng được xử lý nội bộ.

Nếu bạn cần phải tự động thay đổi mọi thứ, thì tại sao không viết kịch bản lệnh vỏ và sau đó thực thi nó (và tất nhiên, sau đó làm sạch)?

28

Tôi cũng gặp sự cố này và hóa ra đây là lỗi trong php (# 11430). Việc sửa lỗi là sử dụng php-cli khi gọi một tập lệnh php khác trong một tập lệnh php. Vì vậy, bạn vẫn có thể sử dụng exec nhưng thay vì sử dụng php sử dụng php-cli khi gọi nó trong trình duyệt:

exec("php-cli somescript.php"); 

Điều này làm việc cho tôi.

+1

Điều này cũng có tác dụng đối với tôi. Ước gì tôi thấy câu trả lời này sớm hơn, sẽ giải quyết được một cơn đau đầu 5 giờ. – Omar

+1

Bạn thưa ông đã cứu ngày của tôi. Đây là câu trả lời chính xác. – DataHerder

+1

Tôi đã tìm kiếm điều này cho HOURS và sắp bỏ cuộc. Lưu ý rằng nếu bạn đang sử dụng PHPSuEXEC, điều này dường như không cần thiết, nhưng ngay sau khi bạn tắt suexec, bạn phải sử dụng php-cli như được chỉ định. – rinogo

1

nếu bạn chỉ đơn giản là chạy tập lệnh php, một cách có thể để thực thi toàn bộ mã là sử dụng hàm include() để chạy tệp php và xuất kết quả bất kỳ. Bạn không thể chuyển đầu ra sang tệp văn bản nhưng nó sẽ xuất hiện trong cửa sổ trình duyệt nếu bạn là kịch bản lệnh Hello World php trông giống như

<?php echo "Hello World!"; ?> 

sau đó nó sẽ nhổ ra trong trình duyệt. Vì vậy, mã thứ hai của bạn sẽ trông như thế

<?php include("helloWorld.php"); echo " PHP ROCKS";?> 

dẫn đến một trang đó sẽ như thế nào,

Hello world! PHP ROCKS

0

Điều này chạy như thể bạn chạy tập lệnh từ trình duyệt.

Điều này xảy ra khi làm việc trên một dự án trên nền tảng Linux.

exec('wget http://<url to the php script>) 

Hy vọng điều này sẽ hữu ích !!

Các vấn đề liên quan