PHP  
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
search for in the  
<pcntl_wtermsigescapeshellarg>
view the version of this page
Last updated: Thu, 21 Aug 2003

LXXXIV. Program Execution functions

Introduction

Those functions provides means to executes commands on the system itself, and means secure such commands.

Requirements

No external libraries are needed to build this extension.

Installation

There is no installation needed to use these functions; they are part of the PHP core.

Runtime Configuration

This extension has no configuration directives defined in php.ini.

Resource Types

This extension has no resource types defined.

Predefined Constants

This extension has no constants defined.

See Also

These functions are also closely related to the backtick operator. Also, while in safe mode you must consider the safe_mode_exec_dir directive.

Table of Contents
escapeshellarg -- escape a string to be used as a shell argument
escapeshellcmd -- escape shell metacharacters
exec -- Execute an external program
passthru --  Execute an external program and display raw output
proc_close --  Close a process opened by proc_open() and return the exit code of that process.
proc_get_status --  Get information about a process opened by proc_open()
proc_nice --  Change the priority of the current process
proc_open --  Execute a command and open file pointers for input/output
proc_terminate --  kills a process opened by proc_open
shell_exec --  Execute command via shell and return complete output as string
system -- Execute an external program and display output


add a note add a note User Contributed Notes
Program Execution functions
jeremy at ntb dot co dot nz
28-Sep-2003 11:18
If an error occurs in the code you're trying to exec(), it can be challenging to figure out what's going wrong, since php echoes back the stdout stream rather than the stderr stream where all the useful error reporting's done. The solution is to add the code "2>&1" to the end of your shell command, which redirects stderr to stdout, which you can then easily print using something like print `shellcommand 2>&1`.
dens at dodgeball dot com
19-Sep-2003 05:41
I was stuck for about an hour and a half last night trying to get Perl to pass back values to my PHP script after running an exec() command.

Since my Perl script was using STDOUT (after being passed command lines variables), I expected the variables used in my .pl script to be accessible in PHP, no questions asked.

Of course, this wasn't working and I finally figured it out with the help of a friend (Shawn = superstar):  you need to echo the exec() command in order to get the values back into PHP. 

Since I was returning multiple values, I added pipe delimiters in my .pl script and then used PHP to parse the string to retreive my data into different variables.

Check it out:

#hit the .pl script with the data
$mydata = exec("script.pl 'command line args' ");
exec("exit(0)");
   
#parse the value that comes back from the .pl script
list($strA, $strB) = split ('[|]', $mydata);
echo "valueA: " . $strA."<br>";
echo "valueB: " . $strB."<br>";

Woo-hoo!
/d
fdqps at alfaproject dot com
15-Sep-2003 06:14
Windows users.

This is just a summarisation of other mails in this list but I hope it will save others some time.

To run the program:
C:\prg Path\program.exe -var1"Hello" -var2"World"
You need to do the following:
$exe = "start /D \"C:\\prg Path\\" \B program.exe -var1\"Hello\" -var2\"World\"";
exec($exe);

As you have a space in the path you need to put it between "". Also ypu need to escape the slash in the path (\\). As you see you need to escape the "" for the two variables.   

Best regards Fredrik
sam at freepeers dot com
30-Aug-2003 07:04
Windows 2000

The only way I found to get a command followed by a filename to execute was with k dot mitz's method:

$cmd = "\"executable\" args file-name";

Example:
$cmd = "\"C:\program files\winzip\wzunzip.exe\" -c C:\\temp\\uploaded_file.zip";
exec($cmd,$output,$rv);

The point to note is that this will not work:

$output = `command file-name`;

So for this case, use exec as shown.
software at yvanrodrigues dot com
30-Jul-2003 04:55
MORE ON THE UNABLE TO FORK MESSAGES IN WINDOWS:

I would like to confirm that this issue relates to permissions on %SYSTEMROOT%\SYSTEM32. The user (usually the anonymous login) must have execute permissions on cmd.exe

This is unlike most other programming languages. For example, in C the spawn and exec functions do not try to open a shell, they create the new process directly. PHP creates the new process via cmd.exe (or command.com) much like the C system() function. This is good for those of you who are trying to run batch files but this is very ineffecient for running other .exe files.

I feel uneasy about lifting permissions in my system32 directory but you can get around this by copying cmd.exe to your PHP directory. Windows will look there first and if it is not there it will check the path. Note: I mean the directory where php.exe is, not your script directory.

I have confirmed this by running filemon.exe while trying to execute a script, and you can see it trying to start the cmd.exe process.
kristof_jebens at hotmail dot com
24-Jun-2003 04:23
For WIN2K Server users running Apache 1.3.22 who are unable to run an executable...

exec('c:\\WINNT\\system32\\cmd.exe /c START c:\\file.exe');

this is the only way it worked for me.
Hope that helps
Darren Gates ( g8z at yahoo dot com )
11-Jun-2003 09:10
Adding to the Windows batch file trick posted by josep on 22-May-2003 ...

The browser will echo the batch file commands. An easy way to hide the echo is to put HTML comments around the system call...

print "<!-- ";
system( "/path/to/BatchFile.bat" );
print " //-->";
david at mego dot com dot tw
03-Jun-2003 01:48
Okay here is my two cents for Windows users having "Unable to fork..." errors when executing "shell_exec" or "system" functions.

After numerous hours of testing, I realized that this error is a result of insufficient file permissions.  You will need to locate c:\Windows\system32\cmd.exe and set the permission to at least Read & Executable for Internet Guest user accounts.

Then you should be able to run your script without a problem.  If you still have a problem feel free to contact me by email.
josep
23-May-2003 02:01
I have tried almost every possible combination of commands for system() and exec().
My goal was to launch a process in the OS and go back to my stuff without waiting for it to finish.
For some reason I have been unable to succeed. Im using WindowsXP Pro(SP1) + Apache 2.0.45 + PHP 4.3.1 (as a module).

Finally, Ive managed to do it with a workaround.
Instead of launching the command directly, I create a BAT file that does it. Then, I issue the command "at" with the BAT file as a parameter. This command returns immediately.

The following code illustrates this:
-----------------------------------------------------
$idimport = getIdImport();
// Flush session info
session_write_close();
// Create the BAT file
$fp = @fopen( "./createreports.cgi.bat", "wb" );
@fwrite( $fp, "cd ".realpath('.')."\r\n" );
@fwrite( $fp, "c:\\php\\cli\\php.exe createreports.cgi.php ".$idimport."\r\n" );
@fclose( $fp );
// Launch the AT command
// Time is set to the next minute
$result = system( 'at '.date("H:i",time()+60).' '.realpath('.').'\createreports.cgi.bat', $retVar );
-----------------------------------------------------

Before struggling with PHP, create a BAT file by hand and double-check that it works. Then add it manually to AT. Check it again. If everything is fine, you can automate it.

Ive had issues with directories. Note that the AT command knows nothing about your "current" directory: you must use full paths.

I have wasted a whole day looking for information and solutions to use exec() and system() and it is sad that they are so poorly implemented on Win32 platforms.
leenoble at spammenot dot ntlworld dot com
09-May-2003 11:37
Even I typed in the full path to a command none of the shell functions worked at all.

exec("/usr/bin/mygoodcommand");

...just didn't produce results.

The command was world executable and ran fine from the shell. But after playing with the 2>&1 thing I established that "mygoodcommand" needed all of its commands to be path specific too. In my case I was attempting to dump a processed uploaded spreadsheet to a database with the command:

mysql --local-infile -u supportadmin --password='*******' personnel < /Users/leenoble/Sites/Websites/Support/data/updateexec.sql

In order for this to work I had to add:

/usr/local/mysql/bin/ to the mysql command to make it work. I hope this helps stop someone else from tearing their hair out in frustration.
mk at neon1 dot net
20-Apr-2003 11:17
If you want to execute background processes from PHP that should run indefinitely, be aware of the following nasty behavior (confirmed with PHP 4.3.1 under FreeBSD, but probably under other flavors of UNIX, too):

PHP internally calls setitimer(2) to set the profiling interval timer (ITIMER_PROF) to enforce execution time limits (max_execution_time and max_input_time). These timer values are passed down to all processes executed by PHP. This means that after such a process has consumed [max_execution_time] seconds of CPU time (not wallclock time!), the system will send it a SIGPROF (signal 27). Since most processes don't use this signal and as such don't call signal(3) to catch or ignore it, the default action is executed, which is to terminate the process.

So if you see background processes that were executed from PHP dying at seemingly random times, you may be experiencing this issue. The solution is simply to call set_time_limit(0) just before executing the process.
Marcin Kosieradzki <phantom at acn dot waw dot pl>
06-Mar-2003 10:14
The shortest hits counter code in PHP ;-) (30 chars)
<?`echo \$((\`cat p\`+1))>p`?>

And version with displayng hit number (40 chars)
<?echo`echo \$((\`cat p\`+1))>p;cat p`?>
goran_johansson at yahoo dot com
19-Feb-2003 09:18
I thought I contribute with how I got background running to work on Windows 2K.
I used the bgrun-exe (www.jukkis.net/bgrun/bgrun.exe) to get this working. I just put this file in my php directory (d:\php)

This is my start.php file:

Hopefully started with BGRUN
<?
// WORKS!!!
$tmp=exec("d:\php\bgrun d:\php\cli\php -q d:\www\myphpapp.php >nul",$res);
?>

When run from a webbrowser it shows the text above and runs myphpapp.php in the background.
jpgiot at ifrance.com
26-Jan-2003 10:30
FOR WINDOWS USERS

i had a look to start command. it's really usefull in fact.

this is how i launch a specific Apache SSL server

<?php
$cmd 
"start /D C:\OpenSA\Apache /B Apache.exe -D SSL";
exec($cmd,$output,$rv);
?>

/D specify the path where application will be launched (equivalent to cd to path)
/B launch application without a console window

so to know the exact parameters of start, you could use

<?php
exec
("start /? > start.txt");
?>

and you will get the help of start in a file named 'start.txt' in the same place you run the script

for WIN 98 you may need to modify a little your command

exec("COMMAND.COM /C START program args >NUL");

(taken from another post)
jfl at eksperten dot dk
11-Jan-2003 02:01
I made my script work in the background like this:
function start_shell ($cmd) {
    exec('nohup "'.$cmd.'" > /dev/null &');
}
// thanks to the users at eksperten.dk
qscripts at lycos dot nl
07-Jan-2003 09:45
Why not using the "start" utility, provided with every version of Windows to start processes in the background on Windows machines? For example :

exec("start song.mp3");

Which will cause the default handeling application for .MP3 file types to start playing the selected song..
NOtvdgeerSPAM at NOxs4allSPAM dot nl
03-Dec-2002 08:36
For users of PHP4 & Apache on Windows2000/XP:

If you're trying to execute a command-line application from PHP that has to show a (console) window on your desktop, make sure you enable the option to 'allow service to interact with desktop' in de service properties of Apache. (See your Windows services)

CAUTION: This can lead to security problems if your setting up a publicly available webserver!
jseverson at myersinternet dot com
12-Oct-2002 02:55
Worked on getting a perl script to run in the background for several hours, and after trying everything posted here on the boards, I came to the conclusion that none were precisely right. Here is the correct way to solve the problem assuming you want to append to your output log file.

exec("perl file_system_path_to_script.cgi parameters >> /tmp/log_file.txt 2>&1 &");
k dot mitz dot NO_SPAM at att dot NO_SPAM dot net
16-Sep-2002 04:07
Newbie note:

The only syntax I found to work for the command portion of an an exec() call on a Win2K devel platform is:

$cmd = "\"path-to-exe\" args file-name";

where 'path-to-exe' has escaped double quotes, args are in the standard format, and 'file-name' has any backslashes escaped.

Example:

$cmd = "\"C:\program files\winzip\wzunzip.exe\" -c C:\\temp\\uploaded_file.zip";

exec($cmd,$output,$rv);

Note that the backslashes are escaped in the uploaded_file name, but not in the path to call the Winzip executable.  Go figure!
kop at meme dot com
13-Aug-2002 04:52
AFICT, the standard Unix Apache configuration causes an rare problem when running a job in the background. The MaxRequestsPerChild directive causes the child to terminate after 1000 requests, any background processes associated with the child will die with the child unless they are started with the "nohup" command.  Thus, the proper way to start a job in the background is to use:

exec('nohup my-command > /dev/null 2>&1 &')
shanx at shanx dot com
09-Aug-2002 01:49
Such a long-winded page, this. But none offered anything useful to me. I needed to execute a simple command, which works at the shell prompt but does not work through the PHP exec. If you do this:

    ---------- CODE ------------

    $result = exec ("ls -ali");

    ---------- /CODE ------------

and find that your variable contains nothing, don't be surprised. Try this instead:

    ---------- CODE ------------

    exec ("ls -ali", $resultArray);
    reset($resultArray);
    while (list ($key, $val) = each ($resultArray))
    {
        $resultLines .= "\n" . trim($val);
    }

    ---------- /CODE ------------

The variable "resultLines" will contain all the results. Hope this helps someone.
ramirosuarez at fibertel dot com dot ar
13-Jul-2002 10:58
For Windows Users:

Keep in mind that a lot of UNABLE TO FORK Errors are the result of insufficient permissions.

CMD.EXE, TEMP Directory (or whatever you specified in php.ini), and all the directories that you use to upload o manipulate your files need to have Write privileges?usually user USER.

This will be useful for all the people who use GD Libraries or other programs that manipulate graphic images.
jeff at jeffglover dot com
02-Jul-2002 06:00
I've been trying to write a process threader in PHP and I couldn't for the life of me get system(), exec() or and of the command functions to sucessfully execute a "lynx -dump" command. It worked fine from the command line, but not from within a php page.

I ended up using the "wget" command (with the background option) to do it, then removed it's log. It's messy, but it works.

exec("wget 'http://www.yoursite.com/threads/thread1.php' -b -O wget-log-1 >&- <&- >/dev/null &");
exec("wget 'http://www.yoursite.com/threads/thread2.php' -b -O wget-log-2 >&- <&- >/dev/null &");
exec("wget 'http://www.yoursite.com/threads/thread3.php' -b -O wget-log-3 >&- <&- >/dev/null &");
exec("wget 'http://www.yoursite.com/threads/thread4.php' -b -O wget-log-4 >&- <&- >/dev/null &");

Good Luck...
GCMXZPJPDJER at spammotel dot com
01-Jul-2002 02:41
to execute a script in background from php you don't need to use mikehup or other tools. just do:

`/usr/bin/php -q foobar.php >/dev/null 2>&1 &`;

mat
deschampsbest at noos dot fr
27-Jun-2002 03:05
I needed to know when a group of background tasks, which had been launched with a call to system, had terminated.
I could not find a function to call, so I created a little function.

It basically loops on the existance of a string in the results returned by the command ps.

All my commands, which run in background have the pid returned by posix_getpid in them.

I am able to launch many background task and effectively wait for them all to finish.

Before this, I would basically would sleep for N seconds.

I apologise if a well known or better method exist.

Thanks,
The New Bee
===============
===============

function wait_until_termination ($id, $duration){
                $i = 0;
                do {
                        $i += 1;

                        $cnt = `ps -auxww |
                                grep $id |
                                grep -v grep |
                                awk '{print $2}' |
                                grep -v $id|
                                wc -l` ;

                        if ($cnt > 0) {
                                sleep ($duration);
                        }

                } while ($cnt != 0);

                echo ("wait_until_termination (PID: $id, SEC: $duration) : LOOPS
:$i<BR>");
        }
ronnyab at online dot no
22-Jun-2002 08:37
Instead of getting the whole package of load average and date, get only the days of uptime!
Use this code:

$uptime = exec("expr $(awk '{print $1}' < /proc/uptime | awk -F. '{print $1}' ) / 86400");
print("Uptime: $uptime days");

This will print "Uptime x days"!
info at businex dot de
17-Jun-2002 07:51
In handing over a parameter to such a background program, I succeeded with the following syntax:

exec("QUERY_STRING='campaign=$campaign'; export QUERY_STRING; php campaign_exec.php &");
rolland dot dudemaine at msg-software dot com
11-Apr-2002 07:45
In case you ever had to chain from php to another program (e.g. with a cgi php that only gives part of the output, or with php-gtk), here is a little C program that kills his parent (php, for instance), then launches a program given in argument.

chain.c :

#include <unistd.h>

int main(int argc, char**argv) {
  /* kill the parent */
  kill(getppid(), 15);
  argv++;
  /* then launch the new program */
  return execvp(argv[0], argv);
}
(compile with gcc -O3 -o chain chain.c)
then in php, use
<?
exec
('chain sh -c echo test');
?>
vi_pa at hotmail dot com
05-Apr-2002 07:17
For those who want to execute a .php script to run in the background, from a
.php web page...

exec("php script.php parameters 2>dev/null >&- <&- >/dev/null &");

Where...
- php is the path to your php script executer (php has to be specifically complied to be to do this)
- script.php is the script
- parameters are none or more parameters
- 2>dev/null redirects the stderr to a file
- <&- switches off the stdin
- >&- switches off the stdout
- >dev/null redirects all other output to the file dev/null
- & direct script to run in background

This is the only way I managed to get it working (Linux & Apache, php 4x enviroment) . What is also great is that the process is forked so even though a user may close the browser that initiated the exec(), the process will still run to completion. And the dev/null file can be turned into a log.

What I found odd is that the script I was execing would run fine in the bg when executed from the command line, but not from the browser until I closed the stdin and stdout.
alan_quill at hotmail dot com
22-Mar-2002 10:36
Simple way to encrypt a password using htpasswd.exe.

$anyname="/path/htpasswd -nb $username $password";

$somename=exec($anyname);

eg.For windows
$command="c:\apache\bin\htpasswd.exe -nb $username $password";

$encrypt=exec($command);
daniel dot hopp at godot dot de
02-Feb-2002 03:25
Re: session_write_close()

To launch a background process within a session, I recommend
to use a start-stop-daemon and ship parameters via ENV.

Example:
----------------------------------------
<?php
 
// Within a session..
 
exec("/some/where/launch.sh 300");
 
// ..finished immediately.
?>

----------------------------------------
#!/bin/bash
# /some/where/launch.sh
T=$1
export T
DAEMON=/some/where/runme.pl
start-stop-daemon --start --quiet --background --exec $DAEMON

----------------------------------------
#!/usr/bin/perl
# /some/where/runme.pl
my $t = $ENV{'T'};
sleep($t);

----------------------------------------
edwin at bit dot nl
23-Jan-2002 07:47
If you are using sessions and want to start a background process, you might have the following problem:
The first time you call your script everything goes fine, but when you call it again and the process is STILL running, your script seems to "freeze" until you kill the process you started the first time.

You'll have to call session_write_close(); to solve this problem. It has something to do with the fact that only one script/process can operate at once on a session. (others will be lockedout until the script finishes)

I don't know why it somehow seems to be influenced by background processes, but I tried everything and this is the only solution. (i had a perl script that "daemonized" it's self like the example in the perl manuals)

Took me a long time to figure out, thanks ian@virtisp.net! :-)
lk1 at reglos dot de
25-Oct-2001 05:05
To keep a program running in the background on win98 the command
exec("COMMAND.COM /C START program args >NUL");
works fine for me.
naken at naken dot cc
16-Aug-2001 04:17
Anyone who still wants a copy of mikehup.c,
I rewrote it:  http://www.naken.cc/mikehup.php
This program will help you run programs in the
background that are called with the php system()
function.
ira dot tonert at e-vendo dot de
21-Jun-2001 09:09
There is a problem by the function exec() and PHP4 under Windows. If you don't get the results line(s) it is possible, that the process hasn't an own console. For IIS 4.0 for example you can switch, that each process get an own console, with following:

1. open a DOS-Box and go to the directory
  "..\winnt\system32\inetsrv\adminsamples"

2. give the following command
  "adsutil set w3svc/CreateCGIWithNewConsole 1"

<pcntl_wtermsigescapeshellarg>
 Last updated: Thu, 21 Aug 2003
show source | credits | sitemap | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: http://php.mirrors.ilisys.com.au/
Last updated: Sat 01 Nov 2003 04:13:36 EST EST