2011-08-17 43 views
261

estoy luchando para entender la diferencia entre shell_exec() y exec() ...PHP shell_exec() vs exec()

Siempre he usado exec() para ejecutar comandos del lado del servidor, cuando se iba a utilizar shell_exec()?

¿Es shell_exec() tan solo una abreviatura de exec()? Parece ser lo mismo con menos parámetros.

+1

buen ejemplo para ver las diferencias es probar estos comandos: 'date',' whoami', 'ifconfig',' netstat'. –

+0

También hay otras funciones: system(), passthru() ... vea esta [pregunta relacionada] (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru), y en particular [esta respuesta] (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru#21016100). –

+0

Posible duplicado de [PHP exec() vs system() vs passthru()] (https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru) – jww

Respuesta

276

shell_exec devuelve todo el flujo de salida como una cadena. exec devuelve la última línea de la salida de forma predeterminada, pero puede proporcionar todos los resultados como una matriz especificada como el segundo parámetro.

Ver

+18

Si necesita la salida- valor Y todo el resultado, probablemente sea mejor usar "exec" en lugar de "shell_exec". Tan pronto como pase el parámetro de salida a "exec", se llenará con cada línea de la salida, me parece "exec" puede todo de "shell_exec" y más :) – Preexo

+4

@ daniel-a-white Lo sé este es uno antiguo, pero es popular, por lo que debe editar su respuesta para reflejar el comentario hecho por @preexo - [exec()] (http://php.net/manual/en/function.exec.php) también tiene la capacidad de devolver todo el resultado si usa sus parámetros opcionales. Además, sin relación, alguien debería comparar los dos comandos para ver cuál es mejor porque @preexo dijo "me parece que' exec() 'puede [hacer] todo' shell_exec() '[can,] y más:) _" – SimpleAnecdote

41

shell_exec - Ejecutar un comando mediante el intérprete de y devolver la salida completa como una cadena

exec - Ejecutar un programa externo.

La diferencia es que con shell_exec obtiene la salida como un valor de retorno.

+3

¡Un resumen breve y conciso! Todavía se debe tener en cuenta que 'exec' devuelve la última línea de la salida. Si lo desea, puede opcionalmente pasar una matriz como el segundo parámetro para capturar la salida completa, y un entero como el tercer parámetro para capturar el valor de retorno del comando de la consola, que se puede usar para la comprobación de errores. La mayor desventaja de 'shell_exec' es que devuelve un valor nulo si el comando falla O si no produce ningún resultado, por lo que su valor de retorno no se puede usar confiablemente para la comprobación de errores. –

57

Aquí están las diferencias. Tenga en cuenta las nuevas líneas al final.

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

Tenga en cuenta que el uso de la backtick operator es idéntica a shell_exec().

Actualización: Realmente debería explicar ese último. Viendo esta respuesta años más tarde, ¡incluso no sé por qué salió en blanco! Daniel lo explica más arriba - es porque exec solo devuelve la última línea, y la última línea de ifconfig está en blanco.

+0

¿Qué ocurre si se produce un error con el comando ...? Recibo el error/No hay tal archivo o directorio, pero ¿cómo puedo capturarlo en una variable ???? –

+0

@AlwinAugustin: ¿Eh? Podría estar siendo escrito en STDERR. Intenta agregar '2> & 1' al final de tu comando para redirigir STDERR a STDOUT si estás en una máquina Linux. – mpen

+0

Lo he agregado también. Pero aún obtengo 0 como valor. He usado un comando wc -l y si el archivo no está allí, necesito obtener el mensaje de error que dice No such such file or directory. –

27

Un par de distinciones que no se han tocado aquí:

  • Con exec(), puede pasar una variable de parámetro opcional que recibirá una serie de líneas de salida. En algunos casos, esto podría ahorrar tiempo, especialmente si el resultado de los comandos ya es tabular.

Compare:

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

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

Por el contrario, si la salida del comando es XML o JSON, y luego tener cada línea como parte de un array no es lo que quiere, ya que necesitará para publicar -procesar la entrada en alguna otra forma, entonces en ese caso use shell_exec.

También vale la pena señalar que shell_exec es un alias para el operador de la parte posterior, para aquellos que utilizan * nix.

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

ejecutivo también es compatible con un parámetro adicional que proporcionará el código de retorno del comando ejecutado:

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

Como se indica en la página del manual shell_exec, cuando realmente se necesita un código de retorno del comando siendo ejecutado, no tiene más remedio que utilizar el ejecutivo.

+3

Además: 'exec' le permite obtener el código de retorno del comando (a través del parámetro' & $ return_var'), mientras que 'shell_exec' no proporciona ninguna forma de obtenerlo. –

+0

Gracias @MarkAmery Mejoré la respuesta con tu comentario. – gview