ChatGPT解决这个技术问题 Extra ChatGPT

PHP shell_exec() vs exec()

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.

good example to see the differences is to try these commands: date, whoami, ifconfig, netstat.
There are also other functions: system(), passthru()… see this related question, and in particular this answer.
Possible duplicate of PHP exec() vs system() vs passthru()

a
aland

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

http://php.net/manual/en/function.shell-exec.php

http://php.net/manual/en/function.exec.php


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 :)
@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() 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 :)"
m
mpen

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.


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 ????
@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.
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.
O
Ondrej Slinták

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.


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.
g
gview

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.


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.
Although the accepted answer is also correct, in my opinion this answer is more important. Probably the best answer would be combination of both.