2011-08-17 45 views
261

Tôi đang đấu tranh để hiểu sự khác biệt giữa shell_exec()exec() ...PHP shell_exec() vs exec()

Tôi luôn sử dụng exec() để thực hiện các lệnh phía máy chủ, khi tôi sẽ sử dụng shell_exec()?

Có phải shell_exec() chỉ là viết tắt của exec()? Nó có vẻ là điều tương tự với ít thông số hơn.

+1

ví dụ tốt để xem sự khác biệt là thử các lệnh sau: 'date',' whoami', 'ifconfig',' netstat'. –

+0

Ngoài ra còn có các chức năng khác: system(), passthru()… xem [câu hỏi liên quan] này (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru), và đặc biệt [câu trả lời này] (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru#21016100). –

+0

Có thể trùng lặp của [PHP exec() vs system() vs passthru()] (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru) – jww

Trả lời

276

shell_exec trả về tất cả luồng đầu ra dưới dạng chuỗi. exec trả về dòng cuối cùng của đầu ra theo mặc định, nhưng có thể cung cấp tất cả đầu ra như một mảng được chỉ định làm tham số thứ hai.

Xem

+18

Nếu bạn cần thoát ra- giá trị VÀ tất cả các đầu ra bạn có lẽ vẫn còn tốt hơn bằng cách sử dụng "exec" chứ không phải là "shell_exec". Ngay sau khi bạn chuyển tham số đầu ra sang "exec", nó sẽ được lấp đầy với mọi dòng đầu ra, có vẻ như tôi "exec" có thể tất cả mọi thứ của "shell_exec" và hơn thế nữa :) – Preexo

+4

@ daniel-a-white Tôi biết đây là một cái cũ, nhưng nó phổ biến vì vậy bạn nên chỉnh sửa câu trả lời của bạn để phản ánh các bình luận được thực hiện bởi @preexo - [exec()] (http://php.net/manual/en/function.exec.php) cũng có khả năng trả về toàn bộ đầu ra nếu bạn sử dụng các tham số tùy chọn của nó. Ngoài ra, không liên quan, một người nào đó nên đánh giá hai lệnh để xem cái nào tốt hơn vì @preexo nói "_it dường như với tôi' exec() 'có thể [làm] mọi thứ' shell_exec() '[có thể,] và nhiều hơn nữa:) _" – SimpleAnecdote

41

shell_exec - Thực hiện lệnh qua vỏ và trả về kết quả hoàn toàn như là một chuỗi

exec - Thực hiện một chương trình bên ngoài.

Sự khác biệt là với shell_exec bạn nhận được kết quả đầu ra dưới dạng giá trị trả về.

+3

Tóm tắt ngắn gọn tuyệt vời! Cần lưu ý rằng 'exec' trả về dòng cuối cùng của đầu ra. Nếu muốn, bạn có thể tùy ý chuyển vào mảng như tham số thứ hai để nắm bắt đầu ra đầy đủ, và một số nguyên làm tham số thứ ba để nắm bắt giá trị trả về của lệnh shell, có thể được sử dụng để kiểm tra lỗi. Nhược điểm lớn nhất đối với 'shell_exec' là nó trả về null nếu lệnh thất bại HOẶC nếu nó không tạo ra bất kỳ đầu ra nào, vì vậy giá trị trả về của nó không thể được sử dụng để kiểm tra lỗi một cách đáng tin cậy. –

57

Dưới đây là sự khác biệt. Lưu ý các dòng mới ở cuối.

> shell_exec('date') 
string(29) "Wed Mar 6 14:18:08 PST 2013\n" 
> exec('date') 
string(28) "Wed Mar 6 14:18:12 PST 2013" 

> shell_exec('whoami') 
string(9) "mark\n" 
> exec('whoami') 
string(8) "mark" 

> shell_exec('ifconfig') 
string(1244) "eth0  Link encap:Ethernet HWaddr 10:bf:44:44:22:33 \n   inet addr:192.168.0.90 Bcast:192.168.0.255 Mask:255.255.255.0\n   inet6 addr: fe80::12bf:ffff:eeee:2222/64 Scope:Link\n   UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1\n   RX packets:16264200 errors:0 dropped:1 overruns:0 frame:0\n   TX packets:7205647 errors:0 dropped:0 overruns:0 carrier:0\n   collisions:0 txqueuelen:1000 \n   RX bytes:13151177627 (13.1 GB) TX bytes:2779457335 (2.7 GB)\n"... 
> exec('ifconfig') 
string(0) "" 

Lưu ý rằng việc sử dụng backtick operator giống hệt với shell_exec().

Cập nhật: Tôi thực sự nên giải thích điều cuối cùng. Nhìn vào câu trả lời này năm sau, ngay cả tôi cũng không biết tại sao nó lại trống rỗng! Daniel giải thích nó ở trên - đó là vì exec chỉ trả về dòng cuối cùng, và dòng cuối cùng của ifconfig xảy ra để trống.

+0

điều gì sẽ xảy ra nếu có một lỗi xảy ra với lệnh ..? Tôi nhận được lỗi/Không có tập tin hoặc thư mục như vậy nhưng làm thế nào tôi có thể nắm bắt nó vào một biến ???? –

+0

@AlwinAugustin: Huh? Có thể được ghi vào STDERR. Hãy thử thêm '2> & 1' vào cuối lệnh của bạn để chuyển hướng STDERR sang STDOUT nếu bạn đang sử dụng máy linux. – mpen

+0

Tôi cũng đã thêm nó. Nhưng tôi vẫn nhận được 0 là giá trị. Tôi đã sử dụng một lệnh wc -l và nếu tập tin không có ở đó, tôi cần nhận được thông báo lỗi nói No such file hoặc directory. –

27

Một vài nét riêng mà không được đề cập đến ở đây:

  • Với exec(), bạn có thể vượt qua một biến param tùy chọn mà sẽ nhận được một mảng của dòng đầu ra. Trong một số trường hợp, điều này có thể tiết kiệm thời gian, đặc biệt nếu đầu ra của các lệnh đã được bảng.

Hãy so sánh:

exec('ls', $out); 
var_dump($out); 
// Look an array 

$out = shell_exec('ls'); 
var_dump($out); 
// Look -- a string with newlines in it 

Ngược lại, nếu đầu ra của lệnh là xml hoặc json, sau đó có mỗi dòng như một phần của một mảng không phải là những gì bạn muốn, vì bạn sẽ cần phải đăng -quá trình đầu vào vào một số hình thức khác, vì vậy trong trường hợp đó sử dụng shell_exec.

Cũng đáng để chỉ ra rằng shell_exec là bí danh cho toán tử ngược, đối với những người được sử dụng để * nix.

$out = `ls`; 
var_dump($out); 

exec cũng hỗ trợ một tham số bổ sung mà sẽ cung cấp mã trở về từ lệnh thực hiện:

exec('ls', $out, $status); 
if (0 === $status) { 
    var_dump($out); 
} else { 
    echo "Command failed with status: $status"; 
} 

Như đã đề cập trong trang hướng dẫn shell_exec, khi bạn thực sự cần một mã trở về từ lệnh là thực hiện, bạn không có lựa chọn nào khác ngoài việc sử dụng exec.

+3

Ngoài ra: 'exec' cho phép bạn lấy mã trả về của lệnh (thông qua tham số' & $ return_var'), trong khi 'shell_exec' không cung cấp cách nào để lấy nó. –

+0

Cảm ơn @MarkAmery Tôi đã cải thiện câu trả lời với nhận xét của bạn. – gview

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