PHP shell_exec () ve exec () karşılaştırması


345

Ben arasındaki farkı anlamak mücadele ediyorum shell_exec()ve exec()...

Her zaman exec()sunucu tarafı komutlarını yürütmek için kullandım , ne zaman kullanmalıyım shell_exec()?

Mi shell_exec()için sadece steno exec()? Daha az parametre ile aynı şey gibi görünüyor.


2
farklılıkları görmek iyi bir örnek bu komutları çalışmaktır: date, whoami, ifconfig, netstat.

Başka işlevler de vardır: system (), passthru ()… bu ilgili soruya ve özellikle de bu cevaba bakınız .
Gras Double

Yanıtlar:


353

shell_exectüm çıkış akışını dize olarak döndürür. execvarsayılan olarak çıktının son satırını döndürür, ancak tüm çıktıyı ikinci parametre olarak belirtilen bir dizi olarak sağlayabilir.

Görmek


21
Çıkış değerine VE tüm çıkışa ihtiyacınız varsa, muhtemelen "shell_exec" yerine "exec" kullanmanız daha iyi olacaktır. Çıktı parametresini "exec" olarak geçer geçmez, çıktının her satırı ile doldurulacak, bana "exec" olabilir "shell_exec" ve daha her şeyi yapabilirsiniz :)
Preexo

4
@ daniel-a-white Bunun eski olduğunu biliyorum, ancak popülerdir, bu yüzden cevabınızı @preexo tarafından yapılan yorumu yansıtacak şekilde düzenlemelisiniz - exec () , isteğe bağlı parametrelerini kullanırsanız tüm çıktıyı döndürme yeteneğine sahiptir. . Ayrıca, ilgisiz, birisi @preexo " bana exec()her şeyi shell_exec()yapabilir [olabilir] ve daha fazla :) "
SimpleAnecdote

77

İşte farklar. Sondaki yeni satırlara dikkat edin.

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

Bu kullanımı dikkat işleci ile aynıdır shell_exec().

Güncelleme: Sonuncuyu gerçekten açıklamalıyım. Yıllar sonra bu cevaba baktığımda bunun neden boş olduğunu bilmiyorum bile! Daniel yukarıda açıklıyor - çünkü execsadece son satırı döndürüyor ve son satırı ifconfigboş kalıyor.


komutu ile bir hata oluşursa ne olur ..? Hata alıyorum / Böyle bir dosya veya dizin yok ama bir değişkene nasıl yakalayabilirim ????
Mutlu Kodlayıcı

@AlwinAugustin: Ha? STDERR'a yazılabilir. 2>&1Linux makinesindeyseniz STDERR'ı STDOUT'a yönlendirmek için komutunuzun sonuna eklemeyi deneyin .
Mart'ta mpen

Ben de ekledim. Ama yine de değer olarak 0 alıyorum. Bir wc -l komutu kullandım ve dosya orada değilse, böyle bir dosya veya dizin yok diyerek hata mesajını almam gerekiyor.
Mutlu Kodlayıcı

50

shell_exec- Komutu kabuk üzerinden yürüt ve tüm çıktıyı dize olarak döndür

exec - Harici bir program yürütün.

Fark, shell_execsizinle birlikte bir dönüş değeri olarak çıktı almanızdır.


4
Güzel özlü özet! Yine de exec, çıktının son satırını döndürdüğüne dikkat edilmelidir . İstenirse, isteğe bağlı olarak bir diziyi tüm çıktıyı yakalamak için ikinci parametre olarak ve üçüncü parametre olarak da kabuk kontrolünün dönüş değerini yakalamak için hata parametresi için kullanılabilecek bir tam sayı iletebilirsiniz. Bunun en büyük dezavantajı shell_exec, komut başarısız olursa VEYA herhangi bir çıktı üretmezse null değerini döndürmesidir, bu nedenle dönüş değeri hata denetimi için güvenilir bir şekilde kullanılamaz.
Sean the Bean

38

Burada ele alınmayan birkaç ayrım:

  • Exec () ile, bir dizi çıktı satırı alacak isteğe bağlı bir param değişkeni iletebilirsiniz. Bazı durumlarda bu, özellikle komutların çıktısı zaten tablo halinde olduğunda zamandan tasarruf edilebilir.

Karşılaştırmak:

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

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

Tersine, komutun çıktısı xml veya json ise, her satırın bir dizinin parçası olarak bulunması istediğiniz şey değildir, çünkü girdiyi başka bir forma daha sonra işlemden geçirmeniz gerekir, bu durumda shell_exec kullanın .

Ayrıca shell_exec'in * nix için kullanılanlar için backtic operatörü için bir takma ad olduğunu belirtmek gerekir.

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

exec, yürütülen komuttan dönüş kodunu sağlayacak ek bir parametreyi de destekler:

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

Shell_exec kılavuz sayfasında belirtildiği gibi, gerçekten yürütülmekte olan komuttan bir dönüş kodu istediğinizde, exec kullanmaktan başka çareniz yoktur.


3
Ayrıca: execKomutun dönüş kodunu ( &$return_varparametre aracılığıyla ) almanızı sağlarken shell_exec, almanın hiçbir yolu yoktur.
Mark Amery

Kabul edilen cevap da doğru olsa da, bence bu cevap daha önemlidir. Muhtemelen en iyi cevap her ikisinin birleşimidir.
UncaAlby
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.