They have slightly different purposes.
exec()is for calling a system command, and perhaps dealing with the output yourself.system()is for executing a system command and immediately displaying the output - presumably text.passthru()is for executing a system command which you wish the raw return from - presumably something binary.
Regardless, I suggest you not use any of them. They all produce highly unportable code.
Answer from Kalium on Stack OverflowThey have slightly different purposes.
exec()is for calling a system command, and perhaps dealing with the output yourself.system()is for executing a system command and immediately displaying the output - presumably text.passthru()is for executing a system command which you wish the raw return from - presumably something binary.
Regardless, I suggest you not use any of them. They all produce highly unportable code.
The previous answers seem all to be a little confusing or incomplete, so here is a table of the differences...
+----------------+-----------------+----------------+----------------+
| Command | Displays Output | Can Get Output | Gets Exit Code |
+----------------+-----------------+----------------+----------------+
| system() | Yes (as text) | Last line only | Yes |
| passthru() | Yes (raw) | No | Yes |
| exec() | No | Yes (array) | Yes |
| shell_exec() | No | Yes (string) | No |
| backticks (``) | No | Yes (string) | No |
+----------------+-----------------+----------------+----------------+
- "Displays Output" means it streams the output to the browser (or command line output if running from a command line).
- "Can Get Output" means you can get the output of the command and assign it to a PHP variable.
- The "exit code" is a special value returned by the command (also called the "return status"). Zero usually means it was successful, other values are usually error codes.
Other misc things to be aware of:
- The shell_exec() and the backticks operator do the same thing.
- There are also proc_open() and popen() which allow you to interactively read/write streams with an executing command.
- Add "2>&1" to the command string if you also want to capture/display error messages.
- Use escapeshellcmd() to escape command arguments that may contain problem characters.
- If passing an $output variable to exec() to store the output, if $output isn't empty, it will append the new output to it. So you may need to unset($output) first.
shell - What are the differences of system(), exec() and shell_exec() in PHP? - Stack Overflow
Running system command from php
Executing unix shell commands using PHP - Stack Overflow
Executing a shell command from PHP with shell_exec - Unix & Linux Stack Exchange
How do malicious hackers use web shells?
How can I detect web shells?
What is a web shell?
Videos
exec — Execute an external program
system — Execute an external program and display the output
shell_exec — Execute command via shell and return the complete output as a string
so if you don't need the output, I would go with exec.
Further details:
- http://php.net/manual/en/function.exec.php
- http://php.net/manual/en/function.system.php
- http://php.net/shell_exec
Just expanding on the existing answer with examples:
All functions will attempt to execute the command almost as if from the terminal. The main difference is in the output and error handling:
exec()
Outputs to var only the last line; Outputs array with each line to 2nd arg; Outputs result_code to 3rd arg -- any non-zero result_code is an error. Here's a list of result_codes
$last_line = exec('pwd;ls -alh', $all_lines_array, $result_code);
echo "LAST_LINE: $last_line";
print_r($all_lines_array);
echo "RESULT_CODE: $result_code";
/*
LAST_LINE: -rw-r--r-- 1 ubuntu psacln 1.2K Feb 7 03:43 index.php
Array
(
[0] => /var/www/vhosts/example.com/httpdocs/dir/subdir
[1] => total 20K
[2] => drwxr-xr-x 3 root root 4.0K Feb 7 03:17 .
[3] => drwxr-xr-x 7 ubuntu psacln 4.0K Feb 6 21:46 ..
[4] => -rw-r--r-- 1 ubuntu psacln 550 Feb 6 22:45 .htaccess
[5] => drwxr-xr-x 2 ubuntu psacln 4.0K Feb 7 00:22 cache
[6] => -rw-r--r-- 1 ubuntu psacln 1.2K Feb 7 03:43 index.php
)
RESULT_CODE: 0
*/
shell_exec()
Outputs single or multiline plain text to var. Takes only 1 arg -- the command
$plain_text = shell_exec('pwd;ls -alh');
echo $plain_text;
/*
/var/www/vhosts/example.com/httpdocs/dir/subdir
total 20K
drwxr-xr-x 3 root root 4.0K Feb 7 03:17 .
drwxr-xr-x 7 ubuntu psacln 4.0K Feb 6 21:46 ..
-rw-r--r-- 1 ubuntu psacln 550 Feb 6 22:45 .htaccess
drwxr-xr-x 2 ubuntu psacln 4.0K Feb 7 00:22 cache
-rw-r--r-- 1 ubuntu psacln 1.2K Feb 7 03:43 index.php
*/
system()
Echos single or multiline plain text. No need for echo system();. result_code is the same as exec()
system('pwd;ls -alh',$result_code);
echo "RESULT_CODE: $result_code";
/*
/var/www/vhosts/example.com/httpdocs/dir/subdir
total 20K
drwxr-xr-x 3 root root 4.0K Feb 7 03:17 .
drwxr-xr-x 7 ubuntu psacln 4.0K Feb 6 21:46 ..
-rw-r--r-- 1 ubuntu psacln 550 Feb 6 22:45 .htaccess
drwxr-xr-x 2 ubuntu psacln 4.0K Feb 7 00:22 cache
-rw-r--r-- 1 ubuntu psacln 1.2K Feb 7 03:43 index.php
RESULT_CODE: 0
*/
Backtick quotes ``
Basically, alias for shell_exec(). Outputs single or multiline plain text to var
$plain_text = `pwd;ls -al`;
echo $plain_text;
/*
/var/www/vhosts/example.com/httpdocs/dir/subdir
total 20K
drwxr-xr-x 3 root root 4.0K Feb 7 03:17 .
drwxr-xr-x 7 ubuntu psacln 4.0K Feb 6 21:46 ..
-rw-r--r-- 1 ubuntu psacln 550 Feb 6 22:45 .htaccess
drwxr-xr-x 2 ubuntu psacln 4.0K Feb 7 00:22 cache
-rw-r--r-- 1 ubuntu psacln 1.2K Feb 7 03:43 index.php
*/
exec() appears to be most versatile as you can iterate over the array of lines, get the last line only, and the result_code.
shell_exec() and backticks `` are great if plain text works better for you.
system() echos automatically :(
exec?
system?
shell_exec?
passthru?
Backticks?
Pfah!
Real developers use proc_open! It has the major and distinct advantage of giving you three PHP streams to feed data into the process, and read both stdout and stderr. This is something that the other process execution functions simply don't do well.
It comes at the small cost of some boilerplate code, so it's a bit more verbose. I consider the trade-off to be excellent.
Oh, and running arbitrary commands from your users is perhaps one of the greatest security risks that you could ever conceive of, but I kind of assume you know this by now.
You could start looking at the php manual:
System program execution
But like sdleihssirhc mentioned, watchout this IS very dangerous and you should NOT allow everything to be executed!
If you still want to do it, to get the output of the shell, just use
exec
The output of the shell will be passed in the second parameter.
E.g.:
exec('ls -la', $outputArray);
print_r($outputArray);
On the php manual for shell_exec, it shows that the function returns the output as a string. If you expect output from the program you launch, you need to capture this like so:
$execQuery = "echo -n test_command";
$output = shell_exec($execQuery);
echo $output;
Your question doesn't show trying to capture any data. If you also make sure to connect stdout and stderr when you run your command, you should get a better idea is what is going on. To use your example:
$output = shell_exec("/usr/bin/oneuser create test10 test10 2>&1");
var_dump($output);
That should help you see what is going on. As Shadur suggests, it seems likely that these programs expect an interactive terminal that can enter passwords in order to run. Even if don't need input, they might expect interactive shells. And he's right that su doesn't play nice in this context. There is, however, a correct tool for the job.
You can setup sudo to such that your http user can execute your program as username without a password but NOT be able to do anything else by running visudo or whatever you use to edit your sudoers file and adding this line:
http ALL=(username) /usr/bin/oneadmin
Then in php your command would look something like this:
$execQuery = "sudo -u username /usr/bin/oneadmin postgres -c '/usr/bin/oneuser create test10 test10'";
$out = shell_exec ("$execQuery 2>&1");
echo $out
Try passthru($cmd);
It will allow user's I/O on the Terminal screen.