Notes

Warning

When allowing user-supplied data to be
passed to this function, use
escapeshellarg() or escapeshellcmd()
to ensure that users cannot trick the system into executing arbitrary
commands.

Note:

If a program is started with this function,
in order for it to continue running in the background, the output of the
program must be redirected to a file or another output stream. Failing to do so
will cause PHP to hang until the execution of the program ends.

Note: When
safe mode is enabled, you can only
execute files within the safe_mode_exec_dir.
For practical reasons, it is currently not allowed to have ..
components in the path to the executable.

User Contributed Notes 53 notes

This is for WINDOWS users. I am running apache and I have been trying for hours now to capture the output of a command.

I'd tried everything that is written here and then continued searching online with no luck at all. The output of the command was never captured. All I got was an empty array.

Finally, I found a comment in a blog by a certain amazing guy that solved my problems.

Adding the string ' 2>&1' to the command name finally returned the output!! This works in exec() as well as system() in PHP since it uses stream redirection to redirect the output to the correct place!

Note to the persons who suggested using backticks for gathering a return value from scripts via system().

Using Backticks is generally frowned upon for security sake. They can be exploited more easily.

Instead, why not use the exec() function with a return parameter specified as an array type. This will allow you to take the full string returned from your script (for example rsync) and return each line in an array.

For example, "echo shell_exec('ls');" will get nothing output,
"my_exec('ls');" will get "sh: ls: command not found",
"my_exec('/bin/ls');" will maybe get "sh: /bin/ls: Permission denied",
and the permission may be caused by selinux.

If you need to run root-level commands, such as to reboot a service, the utility 'sudo' will let you handle linux permissions. In our example we use 'sudo' to allow apache temporary root access to restart a service. We can then use:

system("sudo service dhcpd restart")

You also need to examine the /etc/sudoers file to specify what permissions to grant. Hope this helps someone!

system() will flush the last line retuned from your executed process directly to the output buffer. This you will see in a double echo if you call 'echo system(...)' .To prevent this use exec() insteadorchange output buffering around the call.

It is possible to only capture the error stream (STERR). Here it goes...

(some_command par1 par2 > /dev/null) 3>&1 1>&2 2>&3

-First STDOUT is redirected to /dev/null.-By using parenthesis it is possible to gain control over STERR and STOUT again.-Then switch STERR with STOUT.

The switch is using the standard variable switch method -- 3 variables (buckets) are required to swap 2 variables with each other. (you have 2 variables and you need to switch the contents - you must bring in a 3rd temporary variable to hold the contents of one value so you can properly swap them).

It's important to note that if you are running a series of system() commands in a loop, you need to include the second argument in order for them to run synchonously.

ie)

// this will execute process.php asynchronously; not waiting for completion before executing the next one.$array = array('apple', 'banana', 'pear');foreach($array as $i){system("php process.php \"fruit=$i\"");}

// this will execute process.php 3 times, waiting for the prior command to complete before starting a new one$array = array('apple', 'banana', 'pear');foreach($array as $i){system("php process.php \"fruit=$i\"", $status);}

If your PHP installation permits execution of commands through system() (e.g. you are not running in safe mode, or, if you are, safe_mode_exec_dir contains all the commands you need), you can trigger a backup of your MySQL database, just by pointing your browser to the following script:

If you are not allowed cron access on the web server, you can set up your own cron job to periodically call the above script. If you don't have cron, or a similar functionality on your system, you can still modify the above script to inform the browser to reget the file every xxx hours. A poor man's cron, so to say ;-)

Of course, the $backupdir should at least be protected with a .htaccess file.

And of course, you are not going to backup a really large database this way, if your PHP has some timeout set (as is usually the case with web hosters).

If no headers have been printed, calling the system() function will flush the headers to the client and insert a newline; no further headers or cookies will be transferred to the browser. In version 3.0.7, you will not be warned that the Header() function failed, but will be warned if trying to set a cookie. If you want to continue to send headers after the function call, use exec() instead.

If you are writing CLI scripts in PHP and call external programs which produce some kind of progress bar you should really use passthru() for the output of the external program to go to the terminal immediately.Such progress bar are usually done by outputing the string with "\r" at the end, and contain no "\n". system() and friends look for "\n" before flushing the buffer. As a result, you see nothing during the lengthy operation and suddenly you get the 100% reading, because all output was buffered and quickly replayed into the terminal when the final "\n" has been seen.

If using Windows with IIS and you're having problems with the system() and related commands, I found the easiest way to solve it was to modify the Authentication Method for the file (or directory) that uses the call and change the anonymous access user from the default (IUSR_IMAGE) to a user with enough permissions to execute the commands in the system call. This way, there is no need to give execute permissions to IUSR_IMAGE on cmd.exe (which opens up a security risk system-wide) or copy cmd.exe into your php directory (per the suggestions of others). Hope this helps someone!

I just spent some time learning to use the php system function. I managed to get long file names to work for me. It seems you need to take the same approach that batch files, WSH, and most other programming languages do under WinNT/2K/XP. Putting double quotes around the Path+Filename seems to work. So, something like this should have worked for you:

"c:\program files\apache group\apache2\bin\htpasswd"

Note that if you have parameters, they go OUTSIDE of the last quote. Oh, and don't forget to escape the slashes and quotes!

But you then need to use 'chmod -R 777 to the directory you want to copy it to, which can be done by a

system("chmod -R 777 \"/home/sites/sitexyz/www/$username2\" ");

Now you can execute all the terminal commans via the php, however do realise the security concerns of using the same, especially when the operation is going to preceeded by some user input, so, you need to make sure you filter the inputs, or better not allow user intervention.

I was trying to get the server-side to beep in windows 7. I finally found something that would work without creating my own EXE.

Create a batch file with at the CMD prompt type:

echo @echo (Alt-7)>beep.bat

Then execute it in PHP with:

exec ('start /MIN c:\your_path_here\beep.bat');

NOTE: The only drawback I can find is that a cmd.exe does visually flash on the system (which is why I used the /MIN to ensure it only goes to the taskbar). Not really sure why I don't like that, but it was a side effect that I wasn't looking for.

I've found a very useful technique for the system function. Say if you want to create a page of quotes and you have /usr/games/fortune available. Instead of spending time creating a database and populating it with thousands of quotes, you can just use:

<?phpsystem('/usr/games/fortune');?>

likewise if you want to list the files in your directory, say for example, Mp3's?

If you are trying to parse a CGI script to your webserver which needs arguments, take a look to the virtual() function .. it took me long before i found out it existed...
It's used like this:
<?php
virtual("/cgi-bin/lastuser.cgi?argument");
?>
And that works excellent now for me

If the command printf("%s",system($cmd)); doesn't work, check the httpd.error_log file in your /var/log directory. At my home, the system command can just load binary files in the directory /usr/lib/apache/bin
Stephan.

An example of using the system to call the file command on a linux server. This script detects whether a user posted file is a jpeg, gif or png

<?PHP

$accepted_types=array("JPEG" , "GIF", "PNG");

// The temporary filename of the file in which the uploaded file was stored on the server. if(!empty($_FILES["uploadedfile"])) {$uploaddir = $_SERVER['DOCUMENT_ROOT']."/images/";$uploaddir.=basename( $_FILES['uploadedfile']['name']);

z1a7n8g, your system logging to file function was really useful, but had two errors:$line=fgets($fPtr,filesize("yourfile.php");that line needs a second closing ')'and:while ($line)returns true until your script runs out of memory. Those two lines can be combined:while($line=fgets($fPtr,filesize("yourfile.php")));

Hi,some tips for using a system()-call for batch files on a windows computer:* Write the path to the executable with double back-slashes, like so: C:\\path\\to\\prog.exe* If you are refering to other pathes, e.g. as a parameter, one back-slash works fine.* Do not use SET for declaring parameters - this does not work! Example: SET PATH="C:\path\to\lib" echo path is %PATH%This works fine when started from the comand line, but when called from PHP, the variable is just empty.