393

I'm struggling to understand the difference between shell_exec() and exec()...

I've always used exec() to execute server side commands, when would I use shell_exec()?

Is shell_exec() just a shorthand for exec()? It seems to be the same thing with fewer parameters.

jww
  • 97,681
  • 90
  • 411
  • 885
Ben
  • 60,438
  • 111
  • 314
  • 488
  • 2
    good example to see the differences is to try these commands: `date`, `whoami`, `ifconfig`, `netstat`. –  Sep 04 '12 at 16:35
  • There are also other functions: system(), passthru()… see this [related question](https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru), and in particular [this answer](https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru#21016100). – Gras Double May 24 '17 at 01:50
  • 1
    Possible duplicate of [PHP exec() vs system() vs passthru()](https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru) – jww Feb 21 '18 at 07:20

4 Answers4

392

shell_exec returns all of the output stream as a string. exec returns the last line of the output by default, but can provide all output as an array specifed as the second parameter.

See

aland
  • 1,824
  • 2
  • 26
  • 43
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • 26
    If you need the exit-value AND all of the output you're probably still better of using "exec" rather than "shell_exec". As soon as you pass the output parameter to "exec", it will be filled with every line of the output, it seems to me "exec" can everything of "shell_exec" and more :) – Preexo May 23 '13 at 09:46
  • 4
    @daniel-a-white I know this is an old one, but it's popular so you should edit your answer to reflect the comment made by @preexo - [exec()](http://php.net/manual/en/function.exec.php) also has the ability to return the entire output if you use its optional parameters. Also, unrelated, someone should benchmark the two commands to see which is better becase as @preexo said "_it seems to me `exec()` can [do] everything `shell_exec()` [can,] and more :)_" – SimpleAnecdote Dec 29 '15 at 20:35
  • Also note that trailing whitespace, such as \n, is not included in the $output array of the PHP exec function. So if there is data after the "\n", it may get truncated – 2147483647 Jul 23 '23 at 14:57
85

Here are the differences. Note the newlines at the end.

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

Note that use of the backtick operator is identical to shell_exec().

Update: I really should explain that last one. Looking at this answer years later even I don't know why that came out blank! Daniel explains it above -- it's because exec only returns the last line, and ifconfig's last line happens to be blank.

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • what happens if there is one error occurs with command..? I am getting the error /No such file or directory but how can I capture it to a variable ???? – Happy Coder Mar 11 '13 at 19:43
  • @AlwinAugustin: Huh? Might be being written to STDERR. Try adding `2>&1` to the end of your command to redirect STDERR to STDOUT if you're on a linux machine. – mpen Mar 11 '13 at 21:06
  • I have addedd it also . But still I am getting 0 as the value. I have used one wc -l command and if the file is not there, I need to get the error message saying No such file or directory. – Happy Coder Mar 12 '13 at 04:02
53

shell_exec - Execute command via shell and return the complete output as a string

exec - Execute an external program.

The difference is that with shell_exec you get output as a return value.

Ondrej Slinták
  • 31,386
  • 20
  • 94
  • 126
J0HN
  • 26,063
  • 5
  • 54
  • 85
  • 8
    Nice succinct summary! It should still be noted that `exec` returns the last line of the output. If desired, you can optionally pass in an array as the second parameter to capture the complete output, and an integer as the third parameter to capture the return value of the shell command, which can be used for error checking. The biggest downside to `shell_exec` is that it returns null if the command fails OR if it doesn't produce any output, so its return value cannot reliably be used for error checking. – Sean the Bean Mar 16 '17 at 19:28
43

A couple of distinctions that weren't touched on here:

  • With exec(), you can pass an optional param variable which will receive an array of output lines. In some cases this might save time, especially if the output of the commands is already 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

Conversely, if the output of the command is xml or json, then having each line as part of an array is not what you want, as you'll need to post-process the input into some other form, so in that case use shell_exec.

It's also worth pointing out that shell_exec is an alias for the backtic operator, for those used to *nix.

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

exec also supports an additional parameter that will provide the return code from the executed command:

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

As noted in the shell_exec manual page, when you actually require a return code from the command being executed, you have no choice but to use exec.

gview
  • 14,876
  • 3
  • 46
  • 51
  • 3
    Additionally: `exec` lets you get the return code of the command (via the `&$return_var` parameter), while `shell_exec` provides no way of getting it. – Mark Amery Oct 04 '14 at 22:21
  • 1
    Although the accepted answer is also correct, in my opinion this answer is more important. Probably the best answer would be combination of both. – UncaAlby Oct 10 '19 at 20:56