search for in the  
<proc_terminatesystem>
Last updated: Thu, 19 May 2005

shell_exec

(PHP 4, PHP 5)

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

Description

string shell_exec ( string cmd )

This function is identical to the backtick operator.

Parameters

cmd

The command that will be executed.

Return Values

The output from the executed command.

Examples

Example 1. A shell_exec() example

<?php
$output
= shell_exec('ls -lart');
echo
"<pre>$output</pre>";
?>

Notes

Note: This function is disabled in safe mode.



User Contributed Notes
shell_exec
dk at brightbyte dot de
13-May-2005 03:25
her's a function that is similar to shell_exec but captures both stdout and stderr. It's much more complicated than using 2>&1, but it's independent of the shell and should work on windows, too. It uses proc_open with stream_select and non-blocking streams to read stdout and stderr concurrently. It is not guarantied that the lines appear in the correct order or that they are not intermingeled - but it did not happened when I tested it. So, here goes:

<?php
  
function runExternal($cmd,&$code) {
      
$descriptorspec = array(
          
0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
          
1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
          
2 => array("pipe", "w") // stderr is a file to write to
      
);
      
      
$pipes= array();
      
$process = proc_open($cmd, $descriptorspec, $pipes);
      
      
$output= "";
      
       if (!
is_resource($process)) return false;
      
      
#close child's input imidiately
      
fclose($pipes[0]);
      
      
stream_set_blocking($pipes[1],false);
      
stream_set_blocking($pipes[2],false);
      
      
$todo= array($pipes[1],$pipes[2]);
      
       while(
true ) {
          
$read= array();
           if( !
feof($pipes[1]) ) $read[]= $pipes[1];
           if( !
feof($pipes[2]) ) $read[]= $pipes[2];
          
           if (!
$read) break;
          
          
$ready= stream_select($read, $write=NULL, $ex= NULL, 2);
          
           if (
$ready === false) {
               break;
#should never happen - something died
          
}
          
           foreach (
$read as $r) {
              
$s= fread($r,1024);
              
$output.= $s;
           }
       }
      
      
fclose($pipes[1]);
      
fclose($pipes[2]);
      
      
$code= proc_close($process);
      
       return
$output;
   }
?>

here is how to use it:

<?php
$result
= runExternal("ls -l some-file.txt",$code);

print
"<pre>";
print
$result;
print
"</pre>\n";

print
"<b>code: $code</b>\n";
?>

enjoy :-)
phillipberry at NOSPAM dot blisswebhosting dot com
11-Apr-2005 03:13
I found something odd.

If you run exec then straight after shell_exec the shell_exec will simply not run and will return NULL.

To get it to work i put a sleep(5) after the exec and now shell_exec works fine.
Kenneth
09-Mar-2005 11:19
Sometimes it's needed to be able to execute shell commands as root using PHP. For instance, restarting named after adding or changing zones, or adding new alliases for sendmail.

My approach is to run a server called Nanoweb, available from  http://nanoweb.si.kz/. It's a webserver written in PHP, and needs only the pcntl extension extra to operate. Nanoweb is configured to only listen for connections on localhost, port 81 for example. From my normal PHP scripts running inside Apache I simply call scripts in Nanoweb to get the messy 'root' tasks done. Much more secure and safer.

Hope this helps
03-Jan-2005 11:10
Be careful as to how you elevate privileges to your php script.  It's a good idea to use caution and planing.  It is easy to open up huge security holes.  Here are a couple of helpful hints I've gathered from experimentation and Unix documentation.

Things to think about:

1. If you are running php as an Apache module in Unix then every system command you run is run as user apache.  This just makes sense.. Unix won't allow privileges to be elevated in this manner.  If you need to run a system command with elevated privileges think through the problem carefully!

2. You are absolutely insane if you decide to run apache as root.  You may as well kick yourself in the face.  There is always a better way to do it.

3. If you decide to use a SUID it is best not to SUID a script.  SUID is disabled for scripts on many flavors of Unix.  SUID scripts open up security holes, so you don't always want to go this route even if it is an option.  Write a simple binary and elevate the privileges of the binary as a SUID.  In my own opinion it is a horrible idea to pass a system command through a SUID-- ie have the SUID accept the name of a command as a parameter.  You may as well run Apache as root!
snoj-wwwposter at latitude dot li
29-Sep-2004 04:53
if the script you want to run from shell_exec needs more permissions than the webserver has (for example script needs root priviliges, do:

# chown root:root
# chmod 4711!

of course, replace root:root with the user that the script needs to run as and tweek the chmod for your security policy.

!! be careful about what the script does!  remember it has root privilige!
James McCormack
05-Aug-2004 03:50
I had a perl program which ran fine from command line but not using shell_exec(), exec() or system() - nothing was being returned. I was using the full path and permissions were set correctly.

It turned out the perl program was using more memory than my PHP.INI file was set to allow. Increasing "memory_limit" solved the problem.
leaetherstrip at inbox dot ru
08-Jul-2004 04:23
Note on XP users: XP-Home edition does not allow to set rights directly on files and folders. You should use 'cacls' command-line utility to do this.

For example:

cacls c:\windows\system32\cmd.exe /E /G IUSR_ADMIN2003:F

gives IIS user full access to cmd.exe (potential security hole!), so PHP can fork and execute external programs.
vsuarez at vorealis dot com
30-Jun-2004 08:34
Got the error "Unable to execute..." when trying to run an external program with shell_exec under Windows XP, IIS 5, php 4.3.7  Solved by giving the IIS user (IUSR_...) execution privileges on the system file %systemroot%\system32\cmd.exe  This should be used carefully because may represent a server's security hole.
Jan dot besssai at gmx dot de
03-Apr-2004 10:50
Here is a safe way to create .htpasswd files for .htacces:
<?
//first you need $pas (password), $nam (name) and $fname
//(filename)

if ($pas != "" && $nam!="" && $fname!="")
{
$stdout = shell_exec('htpasswd -n -b -m ' .$nam .' ' .$pas); //starts the htpasswd and outputs the content of the new .passwd file (don't forget to edit the position of the htpasswd executable)
$file = fopen($fname, "a") or
die (
"Can't Open File!!");
fwrite($file, $stdout);
fclose($file);
}
else {
echo
"Missing Parameters!";
}
?>

This way to do it seems to be strange but it is the only way that really worked for me under Win2k3. You can't let htpasswd generate the .htpasswd file directly with windows because programms started by programms started by apache don't have full write-access.
dj-bj at gmx dot net
17-Mar-2004 07:22
shell_exec passes the result to a variable only if the result of the command is true.

When the result is false the generated page contains the error string in clear text at the position the result was fetched (which can differ from reload to reload).

If you would like to recieve also the error messages append 2>&1 to the end of the command you are executing.
However, the result is also passed to the page directly.

To avoid page destruction you should not fetch the result in your script.
By appending >nul to the shell command you can hide any output.
Hope this helps.
Martin Rampersad
11-Jan-2004 03:13
I have PHP (CGI) and Apache. I also shell_exec() shell scripts which use PHP CLI. This combination destroys the string value returned from the call. I get binary garbage.  Shell scripts that start with #!/usr/bin/bash return their output properly.

A solution is to force a clean environment.  PHP CLI no longer had the CGI environment variables to choke on.

<?php

// Binary garbage.
$ExhibitA = shell_exec('/home/www/myscript');

// Perfect.
$ExhibitB = shell_exec('env -i /home/www/myscript');

?>

-- start /home/www/myscript
#!/usr/local/bin/phpcli
<?php

echo("Output.\n");

?>
-- end /home/www/myscript
spagmoid at yahoo dot NOSPAMcom
17-Dec-2003 04:52
Note that whatever you run with this function seems to use PHP memory, so it will die if it exceeds the limit (usually 8 megs)  To do database dumps or other memory-hogging operations use something like system() instead.
jessop <AT> bigfoot <DOT> com
03-Dec-2003 02:19
Just a quick reminder for those trying to use shell_exec on a unix-type platform and can't seem to get it to work. PHP executes as the web user on the system (generally www for Apache), so you need to make sure that the web user has rights to whatever files or directories that you are trying to use in the shell_exec command. Other wise, it won't appear to be doing anything.
ericphp at shepard dot com
23-Nov-2003 04:45
I had major problems getting sell_exec() to work from PHP. It was working fine via the Telnet command line.

Turns out (for me anyway) it was a pathing problem. I'm set up on a VPS FreeBSD server the does not (technically) have root access.

PHP needs to reference the FULL PATH to the app it's calling. But it gets more tricky than that. There may be more than one full path on a server. For instance, on mine there is:

>find ~/ -name mysqldump (VPS non-root search method)

/usr/local/bin/mysqldump
/usr/home/myusername/usr/local/bin/mysqldump
/usr/home/myusername/usr/local/mysql-3.23.41/bin/mysqldump
/usr/home/myusername/usr/local/mysql-3.23.43/bin/mysqldump

Turns out (after 5 hours of hair pulling fun) that /usr/home/myusername/usr/local/mysql-3.23.43/bin/mysqldump was the winner.

The same applies to using cURL and PHP via Cron. /usr/home/myusername/usr/local/curl-7.10.5/bin/curl  works for me there.

And tar wouldn't work until I dug up PHPTAR /usr/home/myusername/usr/local/bin/phptar. Never new that existed ...

Good luck.
moneyboi at fuckwindows dot com
16-Jul-2003 08:46
shell_exec("yourscript.sh") is great for opening shell scripts.
eremi at eremi dot net
09-Jun-2003 12:29
To output the command has it should be, you can do the str_replace trick above, or you can put the output in a <pre> tag.

Example:
<?php
  $output
= shell_exec("[command]");
  echo
"<pre>$output</pre>";
?>
Ben
04-Jun-2003 12:01
When running subprocesses via shell_exec (and maybe others) from Apache/mod_php4, Apache's environment variables don't seem to be passed on to the subprocess environment unless you specifically force them by using putenv something like this:

$remaddr = getenv("REMOTE_ADDR");
putenv("REMOTE_ADDR=$remaddr");
shell_exec("/path/to/subprocess");
dan at mathjunkies.com
15-Apr-2003 11:02
Just a note for anybody who's box is involuntarily running in safemode (i.e. you buy space on a server), or just not working right.  Shell commands won't work.  You can, however, use PHPs FTP functions to FTP in.  I was copying files and making directories, but I assume there might be a way to do something more complex.
mcbeth at broggs dot org
14-Apr-2003 04:18
As far as error checking on the last example.  Several of the shells have the && operator, so you just string your commands together using it instead of ; If at any time any of the programs fail, you will return without running the rest
ron dot petty at unigeek dot com
21-Mar-2003 01:40
Here is an example on how to install software using php

shell_exec("cd /usr/local/src/; gunzip program.tar.gz; tar xvf program.tar; cd program; ./configure; make; make install);

Now depending if your root or not some commands like "make install" may fail.  This doesn't do any error checking, the reason for that is I do not know how to cd to a directory and then execute another command unless they are in the same shell. 

So basically, take what you type on the command line and string them together.
bruce at accumatics dot com
01-Feb-2003 11:24
If you're not getting any output from echo shellexec( "count.pl" ) [for instance], at least try "./count.pl" before bothering with the full path.
flame
29-Jan-2003 08:21
add  '2>&1' to the end of your shell command to have STDERR returned as well as STDOUT.

$shell_return = shell_exec($shell_command." 2>&1");
ryon -at- ryon labaw -dot- com
17-Jan-2003 02:47
Note: You cant used shell_exec() when safemode = on (its disabled), instead use
exec() and copy the needed program into the /nonexec directory (by default, set in php.ini).
dj-bj at gmx dot net
17-Dec-2002 08:27
Running PHP 4.2.3 on Windows 2000 Server shell_exec works fine and passes its output to the variable when the result of the executed command is true.
However, if the command fails and the DOS-shell returns an error the result is no longer availiable in the variable but is passed directly to the page.
yaacov at pleasedontspamme dot spam
29-Oct-2002 12:46
If you're running scripts or commands and can't figure out what's not working, check to make sure that you're not using an alias in place of a command. PHP (quite reasonably) doesn't seem to recognise aliases.
php at chris-decker dot com
24-Jun-2002 01:12
I have found it easiest to use the following code to execute a shell command and return all of it's output (not just the last line) to the user as if he/she were sitting at the terminal:

$output = shell_exec("$command");
echo(nl2br($output));
matt_smith&uconn_edu
18-Jun-2002 11:51
Re: executing scripts that work on command line, but not from PHP system() calls -- Make sure you include the full path to the executable.
tonysb at gmx dot net
30-Mar-2002 02:57
shell_exec is extremely useful as a substitute for the virtual() function where unavailable (Microsoft IIS for example). All you have to do is remove the content type string sent in the header:

<?
$mstrng
= shell_exec('yourcgiscript.cgi');
$mstrng = ereg_replace( "Content-type: text/html", "", $mstrng );
echo
$mstrng;
?>

This works fine for me as a substitute for SSI or the virtual() func.

Anton Babadjanov
http://www.vbcn.com.ar

<proc_terminatesystem>
 Last updated: Thu, 19 May 2005
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: The Server Pages
Last updated: Thu May 19 17:35:34 2005 CDT