PHP shell_exec () vs exec ()


345

Sto lottando per capire la differenza tra shell_exec()e exec()...

Ho sempre usato exec()per eseguire i comandi lato server, quando avrei usato shell_exec()?

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


2
buon esempio per vedere le differenze è quello di provare questi comandi: date, whoami, ifconfig, netstat.

Ci sono anche altre funzioni: system (), passthru () ... vedi questa domanda correlata , e in particolare questa risposta .
Gras Double

1
jww

Risposte:


353

shell_execrestituisce tutto il flusso di output come stringa. execrestituisce l'ultima riga dell'output per impostazione predefinita, ma può fornire tutto l'output come un array specificato come secondo parametro.

Vedere


21
Se hai bisogno del valore di uscita E di tutto l'output, probabilmente stai ancora meglio usando "exec" piuttosto che "shell_exec". Non 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 che questo è vecchio, ma è popolare quindi dovresti modificare la tua risposta per riflettere il commento fatto da @preexo - exec () ha anche la possibilità di restituire l'intero output se usi 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()[possibile,] e altro :) "
SimpleAnecdote

77

Ecco le differenze Nota le nuove righe 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) ""

Si noti che l'uso dell'operatore backtick è identico a shell_exec().

Aggiornare: dovrei davvero spiegare l'ultimo. Guardando questa risposta anni dopo, non so nemmeno perché sia ​​uscito in bianco! Daniel lo spiega sopra - è perché execrestituisce solo l'ultima riga e ifconfigl'ultima riga sembra essere vuota.


cosa succede se si verifica un errore con il comando ..? Ricevo l'errore / Nessun file o directory, ma come posso acquisirlo in una variabile ????
Happy Coder

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

L'ho aggiunto anche io. Ma sto ancora ottenendo 0 come valore. Ho usato un comando wc -l e se il file non è presente, devo ottenere il messaggio di errore che dice No file o directory.
Happy Coder

50

shell_exec- Eseguire il comando tramite shell e restituire l'output completo come stringa

exec - Eseguire un programma esterno.

La differenza è che con shell_execte ottieni l'output come valore di ritorno.


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

38

Un paio di distinzioni che non sono state toccate qui:

  • Con exec (), è possibile passare una variabile param opzionale che riceverà una matrice di linee di output. In alcuni casi ciò potrebbe far risparmiare tempo, soprattutto se l'output dei comandi è già tabulare.

Confrontare:

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, avere ciascuna riga come parte di un array non è quello che desideri, poiché dovrai post-elaborare l'input in qualche altra forma, quindi in questo caso usa shell_exec .

Vale anche la pena sottolineare che shell_exec è un alias per l'operatore backtic, per quelli abituati a * 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 notato nella pagina del manuale shell_exec, quando in realtà si richiede un codice di ritorno dal comando in esecuzione, non si ha altra scelta che usare exec.


3
Inoltre: execconsente di ottenere il codice di ritorno del comando (tramite il &$return_varparametro), shell_execsenza fornire alcun modo per ottenerlo.
Mark Amery,

Anche se la risposta accettata è corretta, secondo me questa risposta è più importante. Probabilmente la risposta migliore sarebbe una combinazione di entrambi.
UncaAlby,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.