PHP shell_exec () vs exec ()

345

Saya berjuang untuk memahami perbedaan antara shell_exec()dan exec()...

Saya selalu terbiasa exec()menjalankan perintah sisi server, kapan saya akan gunakan shell_exec()?

Apakah shell_exec()hanya singkatan untuk exec()? Tampaknya menjadi hal yang sama dengan parameter yang lebih sedikit.

Webnet
sumber
2
contoh yang baik untuk melihat perbedaan adalah untuk mencoba perintah ini: date, whoami, ifconfig, netstat.
Ada juga fungsi-fungsi lain: system (), passthru () ... lihat pertanyaan terkait ini , dan khususnya jawaban ini .
Gras Double
1
Kemungkinan rangkap dari PHP exec () vs system () vs passthru ()
jww

Jawaban:

353

shell_execmengembalikan semua aliran output sebagai string. execmengembalikan baris terakhir dari output secara default, tetapi dapat memberikan semua output sebagai array yang ditentukan sebagai parameter kedua.

Lihat

Daniel A. White
sumber
21
Jika Anda membutuhkan nilai keluar DAN semua output Anda mungkin masih lebih baik menggunakan "exec" daripada "shell_exec". Segera setelah Anda mengirimkan parameter output ke "exec", itu akan diisi dengan setiap baris output, menurut saya "exec" dapat semuanya "shell_exec" dan banyak lagi :)
Preexo
4
@ daniel-a-white Saya tahu ini adalah yang lama, tapi ini populer sehingga Anda harus mengedit jawaban Anda untuk mencerminkan komentar yang dibuat oleh @preexo - exec () juga memiliki kemampuan untuk mengembalikan seluruh output jika Anda menggunakan parameter opsionalnya . Juga, tidak terkait, seseorang harus membandingkan dua perintah untuk melihat mana yang lebih baik karena @preexo mengatakan " bagi saya sepertinya exec()[melakukan] segalanya shell_exec()[bisa,] dan banyak lagi :) "
SimpleAnecdote
77

Inilah perbedaannya. Perhatikan baris baru di bagian akhir.

> 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) ""

Perhatikan bahwa penggunaan operator backtick identik dengan shell_exec().

Pembaruan: Saya benar-benar harus menjelaskan yang terakhir. Melihat jawaban ini bertahun-tahun kemudian bahkan saya tidak tahu mengapa jawaban itu kosong! Daniel menjelaskannya di atas - itu karena exechanya mengembalikan baris terakhir, dan ifconfigbaris terakhir kebetulan kosong.

Mpen
sumber
apa yang terjadi jika ada satu kesalahan terjadi dengan perintah ..? Saya mendapatkan kesalahan / Tidak ada file atau direktori tetapi bagaimana saya bisa menangkapnya ke variabel ????
Selamat Coder
@AlwinAugustin: Hah? Mungkin sedang ditulis untuk STDERR. Coba tambahkan 2>&1ke akhir perintah Anda untuk mengarahkan STDERR ke STDOUT jika Anda menggunakan mesin linux.
mpen
Saya telah menambahkannya juga. Tapi saya tetap mendapatkan 0 sebagai nilainya. Saya telah menggunakan satu perintah wc -l dan jika file itu tidak ada, saya perlu mendapatkan pesan kesalahan yang mengatakan Tidak ada file atau direktori tersebut.
Selamat Coder
50

shell_exec- Jalankan perintah via shell dan kembalikan output lengkap sebagai string

exec - Jalankan program eksternal.

Perbedaannya adalah bahwa dengan shell_execAnda mendapatkan output sebagai nilai balik.

J0HN
sumber
4
Ringkasan ringkas yang bagus! Masih harus dicatat bahwa execmengembalikan baris terakhir dari output. Jika diinginkan, Anda dapat secara opsional mengirimkan array sebagai parameter kedua untuk menangkap output lengkap, dan integer sebagai parameter ketiga untuk menangkap nilai kembali dari perintah shell, yang dapat digunakan untuk pengecekan kesalahan. Kelemahan terbesar shell_execadalah bahwa ia mengembalikan nol jika perintah gagal ATAU jika tidak menghasilkan output, sehingga nilai kembalinya tidak dapat digunakan untuk memeriksa kesalahan.
Sean the Bean
38

Beberapa perbedaan yang tidak disentuh di sini:

  • Dengan exec (), Anda dapat melewatkan variabel param opsional yang akan menerima larik garis output. Dalam beberapa kasus ini mungkin menghemat waktu, terutama jika output dari perintah sudah tabular.

Membandingkan:

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

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

Sebaliknya, jika output dari perintah adalah xml atau json, maka memiliki setiap baris sebagai bagian dari array bukanlah apa yang Anda inginkan, karena Anda harus memposting-proses input ke dalam bentuk lain, jadi dalam hal ini gunakan shell_exec .

Perlu juga disebutkan bahwa shell_exec adalah alias untuk operator backtic, bagi mereka yang terbiasa * nix.

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

exec juga mendukung parameter tambahan yang akan memberikan kode kembali dari perintah yang dijalankan:

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

Seperti dicatat dalam halaman manual shell_exec, ketika Anda benar-benar membutuhkan kode kembali dari perintah yang dieksekusi, Anda tidak punya pilihan selain menggunakan exec.

gview
sumber
3
Selain itu: execmemungkinkan Anda mendapatkan kode pengembalian perintah (melalui &$return_varparameter), sementara shell_exectidak memberikan cara untuk mendapatkannya.
Mark Amery
Meskipun jawaban yang diterima juga benar, menurut saya jawaban ini lebih penting. Mungkin jawaban terbaik adalah kombinasi keduanya.
UncaAlby