2010-11-09 60 views
11

Tôi cần chạy các tập lệnh sau.Hệ thống PHP() - trạng thái trả về luôn là 0

// File: script_a.php 
<?php exit(1); ?> 

// File: script_b.php 
<?php 
    system('php script_a.php', $return); 
    var_dump($return); 
?> 

Bây giờ vấn đề của tôi: Trên hệ thống cửa sổ của tôi đang chạy script_b.php hiển thị int(1) như mong đợi. Trên Unix-Server của chúng tôi, tôi luôn nhận được int(0), điều khiến tôi không thể kiểm tra, nếu một lỗi nhất định xảy ra bên trong script_a.php.

Có ai biết vấn đề này và cách giải quyết không?

+2

'$?' Chứa gì khi chạy script_a.php từ dòng lệnh? –

+0

Phiên bản php nào bạn đang sử dụng trên máy chủ Unix, so sánh với các cửa sổ – RobertPitt

+0

Nếu tôi chạy script_b từ dòng lệnh, mọi thứ hoạt động tốt. $ Là gì? –

Trả lời

0

Bạn đã kiểm tra xem safe_mode có được bật trên máy chủ Unix không?

PHP Lưu ý:

Lưu ý: Khi chế độ an toàn được bật, bạn chỉ có thể chạy các file trong safe_mode_exec_dir. Vì lý do thực tế , hiện tại không được phép có các thành phần .. trong đường dẫn đến thực thi.

Hoặc có thể chức năng hệ thống bị cấm thực hiện?

+0

safe_mode bị tắt. Và hệ thống được phép gọi. Nếu tôi đặt một số câu lệnh echo trong script_a trước khi thoát, tôi thường có thể lấy kết quả đó, nhưng trạng thái thoát vẫn là 0. –

+0

bạn đã thử các phương thức thực thi khác chưa? có thể exec() hoặc passthru() hoạt động đúng – Rodrigo

+0

Tôi đã thử cả hai, exec() và passthru(). Trên dòng lệnh kết quả là như mong đợi nhưng thực hiện trên máy chủ web kết quả trong $ return là 0. –

1

Bạn có thể muốn kiểm tra xem nó có đang thực thi php đúng trên máy Unix hay không. Trên nhiều hệ thống UNIX, bạn sẽ cần phải gọi php-cli thực thi được insted của php một để sử dụng trên dòng lệnh. Một điều cần kiểm tra khác là quyền. Có lẽ người dùng thực thi kịch bản script_b.php không có quyền thực thi script_a?

1

__halt_compiler() được gọi ở đâu đó, có thể kiểm tra điều đó?

+3

. H h à? –

+0

@Ignacio - tôi có thể sao chép cùng một đầu ra khi nhúng '__halt_compiler(); exit (1); ', và có thể PHP trong bí danh unix thành một cái gì đó? – ajreal

+0

Nó sẽ không thất bại trên cả hai nền tảng trong trường hợp đó? –

1

Hãy thử thực hiện cuộc gọi PHP system với đường dẫn tuyệt đối của cả tệp thực thi PHP và tên tệp tập lệnh, ví dụ: system('/usr/bin/php /path/to/script_a.php', $return);. Có lẽ đó là một vấn đề đường dẫn. (Bạn có thể tìm thấy đường dẫn tuyệt đối của tệp thực thi PHP của bạn với: which php).

Ngoài ra, như một người được đề xuất, hãy thử gỡ lỗi giá trị trả về thực tế của script_a.php trên máy chủ UNIX của bạn bằng cách chạy php script_a.php; echo $? trên dòng lệnh. Điều đó echo sẽ xuất ra giá trị trả về cuối cùng, tức là giá trị được trả về bởi script_a.php.

Dù sao, tôi đề nghị thực hiện một số include với tuyên bố return như được mô tả trong Ví dụ số 5 của số include() documentation. Nếu bạn có thể điều chỉnh kịch bản của mình như thế này, đó là cách giao tiếp hiệu quả hơn.

// File: script_a.php 
<?php return 1; ?> 

// File: script_b.php 
<?php 
    $return = (include 'script_a.php'); 
    var_dump($return); 
?> 
0

Tôi không thể tạo lại nó (PHP 5.3.3, Ubuntu).

Khi tôi đặt lối ra có giá trị đến một cái gì đó tốt hơn grep-thể, như "666", truy tìm các kịch bản cũng trở gì được mong đợi:

strace -f php5 script_b.php 2>&1 | grep EXITSTATUS 

[pid 18574] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0, NULL) = 18575 
waitpid(18574, [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0) = 18574 

Các "-f" để strace hãy nó theo con quy trình khi bạn sử dụng cuộc gọi hệ thống. "2> & 1" chuyển hướng stderr thành stdout để cho mọi thứ grep. Bạn cũng có thể ống nó để "| ít" để đi qua nhưng đầu ra là dài và không phải là rất dễ đọc.

0

Tôi không thể tạo lại điều này trên hệ thống của mình, Ubuntu Hardy.Dưới đây là một ví dụ:

/tmp$ mkdir /tmp/sbuzz 
/tmp$ cd /tmp/sbuzz 
/tmp/sbuzz$ echo '<?php exit(1); ?>' >script_a.php 
/tmp/sbuzz$ cat >script_b.php 
<?php 
    system('php script_a.php', $return); 
    var_dump($return); 
?> 
/tmp/sbuzz$ php script_b.php 
int(1) 
/tmp/sbuzz$ echo '<?php exit(2); ?>' >script_a.php 
/tmp/sbuzz$ php script_b.php 
int(2) 
/tmp/sbuzz$ 

Thoát mã 0 có nghĩa là thực hiện thành công của chương trình, vì vậy nó loại âm thanh như bạn đang có lẽ chạy script_a.php sai hoặc có lẽ là "php" thực thi không được làm những gì bạn đang mong đợi? Có lẽ bạn có một kịch bản gọi là "php" đó là trong con đường của bạn trước khi thông dịch viên? Báo cáo "php" nào? Trên hệ thống của tôi nó nói "/ usr/bin/php".

Nếu PHP không thể tìm thấy kịch bản, nó sẽ thoát ra với 1, ví dụ:

/tmp/sbuzz$ cat script_b.php 
<?php 
    system('php doesnt_exist_script_a.php', $return); 
    var_dump($return); 
?> 
/tmp/sbuzz$ php script_b.php 
Could not open input file: doesnt_exist_script_a.php 
int(1) 
/tmp/sbuzz$ 

Trong trường hợp này tôi đã thay đổi script_b.php để cố gắng chạy một kịch bản không tồn tại, và tôi nhận được mã thoát 1 (nó phải là 2 nếu nó hoàn thành thành công, bởi vì tôi đã thay đổi script_a ở trên), nhưng nó cũng cho thấy lỗi mà nó không thể chạy chương trình.

Bạn có thể muốn thử thay đổi nó để đặc biệt chạy đường dẫn đầy đủ để thực thi PHP:

system('/usr/bin/php script_a.php') 

hay còn đầy đủ đường dẫn đến kịch bản cũng như:

system('/usr/bin/php /tmp/sbuzz/script_a.php') 

Bạn cũng có thể hãy thử thực hiện cụ thể chương trình sẽ trả về 1, giống như một điểm dữ liệu khác, chẳng hạn như:

system('false') 
system('bash -c "exit 69"') 

Bạn có thể muốn thử một mã thoát khác hơn 1, đây là lỗi thường gặp. Đó là lý do tại sao tôi đã "thoát 69" ở trên. "False" sẽ thoát ra với 1.

Ngoài ra, tất nhiên, hãy thử chạy script_a.php trực tiếp:

/tmp/sbuzz$ php script_a.php 
/tmp/sbuzz$ echo $? 
2 
/tmp/sbuzz$ 

Các "$?" là mã thoát của lệnh chạy cuối cùng, tại dấu nhắc trình bao.

-3

Bạn có thể thử chuyển giá trị bát phân để thoát(). Xem những gì xảy ra sau đó.

+0

Tiếp theo thời gian tôi sẽ đăng câu trả lời này làm bình luận, sau đó nó không thể bỏ phiếu. – xaav

0

Hãy thử:

<?php 
    die(1); 
?> 

Nếu thất bại là tốt, kiểm tra thiết bị xuất chuẩn của:

strace php script_a.php 
-1

bạn cần phải được chạy như là người chủ hoặc sử dụng sudo để truy cập thông qua php.

thử một cái gì đó như thế này: -

system('sudo /usr/bin/php -f script_a.php', $return); 

trong script_b.php bạn

và chỉnh sửa/etc/sudoers để thêm dòng sau: -

apache ALL=(ALL) NOPASSWD: /usr/bin/php -f script_a.php 

nếu php không phải là trong/usr/bin/php thay đổi tham khảo và cũng đề cập đến đường dẫn đầy đủ của tập tin script_a.php somthing như /var/www/html/script_a.php hoặc đường dẫn nơi nó nằm trên thực tế.

Cảm ơn.

+0

Có an toàn không? – mattalxndr

+2

tại sao bạn sẽ cần hoặc muốn sử dụng sudo cho một trường hợp như thế này? đây là một cơn ác mộng an ninh. xấu, xấu, xấu, xấu, ý tưởng tồi. – taxilian

+0

Vui lòng đọc liên kết này có thể xóa các nghi ngờ http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch09_:_Linux_Users_and_Sudo –

0

Không chắc chắn nếu những vấn đề này có liên quan, nhưng bạn có thể nhìn vào exec always returns -1 (or 127) vì tôi đã có một vấn đề tương tự trong quá khứ ... ngay cả khi tôi đã không giải quyết nó một cách nhẹ nhàng. Trong trường hợp của bạn, nó có thể là một vấn đề khác, không chắc chắn làm thế nào nó có thể tái tạo, nhưng tôi đã thấy caeses nơi chuỗi trả về cho một lệnh không rõ sẽ là chuỗi trả về từ bash (bash: command not found). Trên hầu hết các máy chủ tôi không có gì mặc dù. Bạn có thể thử và kiểm tra các thiết lập vỏ cho người dùng hiện (i giả định nó sẽ là www-data)

0

Lấy trong việc xem xét bình luận của bạn rằng vấn đề của bạn đang xảy ra trong hệ thống UNIX khi script_b của bạn là một cái gì đó giống như

hệ thống ('php script_a.php | tee myLogFile', $ return);

Bạn có thể sử dụng cú pháp này

hệ thống ("bash -c 'php script_a.php | tee log.txt; exit \ $ {PIPESTATUS [0]}'", $ trở về);

Làm người đàn ông bash và tìm kiếm PIPESTATUS để biết thêm chi tiết.

0

Tôi biết đây là một chủ đề cũ, nhưng tôi chỉ có một vấn đề tương tự.

Các trạng thái thoát đã được đặt thành 0 khi tôi đã có kịch bản chạy ở chế độ nền, một cái gì đó giống như

system('php script_a.php &', $return); 

thể bạn đã làm điều đó nhưng chỉ khái quát hóa cho dễ đọc?

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