2011-08-17 8 views
261

sto lottando per capire la differenza tra shell_exec() e exec() ...PHP shell_exec() vs exec()

ho sempre usato exec() per eseguire i comandi lato server, quando userei shell_exec()?

È shell_exec() solo una scorciatoia per exec()? Sembra essere la stessa cosa con meno parametri.

+1

Un buon esempio per vedere le differenze è provare questi comandi: 'date',' whoami', 'ifconfig',' netstat'. –

+0

Ci sono anche altre funzioni: system(), passthru() ... vedi questa [domanda correlata] (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru), e in particolare [questa risposta] (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru#21016100). –

+0

Possibile duplicato di [PHP exec() vs system() vs passthru()] (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru) – jww

risposta

276

shell_exec restituisce tutto il flusso di output come una stringa. exec restituisce l'ultima riga dell'output per impostazione predefinita, ma può fornire tutto l'output come una matrice specificata come secondo parametro.

Vedi

+18

Se è necessario l'exit- value AND all output probabilmente stai ancora meglio usando "exec" piuttosto che "shell_exec". Appena si passa il parametro di output a "exec", verrà riempito con ogni riga dell'output, mi sembra che "exec" possa tutto di "shell_exec" e altro :) – Preexo

+4

@ daniel-a-white so questo è vecchio, ma è popolare quindi è necessario modificare la risposta per riflettere il commento fatto da @preexo - [exec()] (http://php.net/manual/en/function.exec.php) ha anche la possibilità di restituire l'intero output se si utilizzano i suoi parametri opzionali. Inoltre, non correlato, qualcuno dovrebbe confrontare i due comandi per vedere quale è meglio perché @preexo ha detto "mi sembra che exec()' possa [fare] tutto 'shell_exec()' [can,] e altro:) _ " – SimpleAnecdote

41

shell_exec - Esegue comando attraverso la shell e restituire l'output completo come stringa

exec - Esegue un programma esterno.

La differenza è che con shell_exec si ottiene l'output come valore di ritorno.

+3

Bel riassunto succinto! Va comunque notato che 'exec' restituisce l'ultima riga dell'output. Se lo si desidera, è possibile passare facoltativamente un array come secondo parametro per acquisire l'output completo e un intero come terzo parametro per acquisire il valore restituito del comando shell, che può essere utilizzato per il controllo degli errori. Il più grande svantaggio di 'shell_exec' è che restituisce null se il comando fallisce OPPURE se non produce alcun output, quindi il suo valore di ritorno non può essere usato in modo affidabile per il controllo degli errori. –

57

Ecco le differenze. Nota le newline alla fine.

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

nota che l'utilizzo del backtick operator è identico a shell_exec().

Aggiornamento: Devo davvero spiegare l'ultimo. Guardando questa risposta anni dopo, anche io non so perché è venuto fuori in bianco! Daniel lo spiega sopra: è perché exec restituisce solo l'ultima riga e l'ultima riga di ifconfig è vuota.

+0

cosa succede se c'è un errore si verifica con il comando ..? Sto ottenendo l'errore/Nessun file o directory di questo tipo, ma come posso catturarlo in una variabile ???? –

+0

@AlwinAugustin: Huh? Potrebbe essere scritto su STDERR. Prova ad aggiungere '2> & 1' alla fine del tuo comando per reindirizzare STDERR su STDOUT se sei su una macchina Linux. – mpen

+0

L'ho aggiunto anche io. Ma ancora ottengo 0 come valore. Ho usato un comando wc -l e se il file non è lì, ho bisogno di ottenere il messaggio di errore dicendo No tale file o directory. –

27

Un paio di distinzioni che non sono stati toccati qui:

  • con exec(), è possibile passare una variabile param opzionale che riceveranno una serie di linee di uscita. In alcuni casi ciò potrebbe far risparmiare tempo, specialmente se l'output dei comandi è già tabellare.

Confronta:

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

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

Al contrario, se l'output del comando è XML o JSON, allora avere ogni riga come parte di un array non è ciò che si vuole, come avrete bisogno di inviare -elaborare l'input in qualche altro modulo, quindi in questo caso utilizzare shell_exec.

Vale anche la pena sottolineare che shell_exec è un alias per l'operatore di retromarcia, per quelli usati per * nix.

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

exec supporta anche un parametro aggiuntivo che fornirà il codice di ritorno dal comando eseguito:

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

Come indicato nella pagina di manuale shell_exec, quando in realtà bisogno di un codice di ritorno dal comando di essere eseguito, non hai altra scelta che usare exec.

+3

Inoltre: 'exec' consente di ottenere il codice di ritorno del comando (tramite il parametro' & $ return_var'), mentre 'shell_exec' non fornisce alcun modo per ottenerlo. –

+0

Grazie a @MarkAmery ho migliorato la risposta con il tuo commento. – gview