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

LXXXIII. Funktionen zur Programmausf�hrung

Diese Funktionen stellen Mittel und Wege zur Verf�gung, Befehle und externe Programme auf dem System selbst auszuf�hren und diese Ausf�hrung sicher durchzuf�hren. Diese Funktionen stehen in enger Beziehung zum Backtick-Operator.

Inhaltsverzeichnis
escapeshellarg --  Maskiert eine Zeichenkette (String), um sie als Shell-Argument benutzen zu k�nnen
escapeshellcmd -- Maskiert Shell-Metazeichen
exec -- F�hrt ein externes Programm aus
passthru --  F�hrt ein externes Programm aus und zeigt dessen Ausgabe an
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_open --  Execute a command and open file pointers for input/output
shell_exec --  Execute command via shell and return complete output as string
system --  F�hrt ein externes Programm aus und zeigt dessen Ausgabe an.


User Contributed Notes
Funktionen zur Programmausf�hrung
add a note
aulbach at unter dot franken dot de
04-Jun-1999 11:39

Wondering, why your command isn�t printing anything?


Perhaps your command fails? But why isn�t there any error message in your browser?


Under Unix the error ouput goes into another filehandle. Use this "trick" to see your errors:


<PRE>
        system("touch /forbidden 2>&1");
</PRE>
This will pipe any output from ERROROUT into STDOUT (works with most shells, see docs of used shell, if this isn�t working).

nemo
03-Aug-1999 07:00

On the off chance you always get the same return value (in my case 11, although it may differ) when you call <code>passthru</code>, or <code>exec</code>, you may want to investigate the possibility that the desired command is segfaulting during the <code>exec</code>.

Writing text out at the very start does not always work: the pipes aren't always emptied.



If you want to know about a few return values, check out the man page for <code>sh</code>.

naken at i1 dot net
01-Dec-1999 05:32

For anyone interested in execing in the background I figured out how to do it.  I wrote a
small C program (You can see it at ) that forks a process and closes off STDIN,STDOUT,STDERR)..  then all you do is call exec with:  exec("/path/to/mikehup whatever &"); and PHP will come back and your process will run in the background :) this is the only way i've been able to do it...

kop at meme dot com
23-Jan-2000 12:00

These functions all execute the given command in a shell, so standard shell redirection, command sequencing, piping, etc. can be used.


There appears to be no way to execute a command, feed it stuff on standard in, and retreive the return code and the output sent to standard out (not to mention standard error).  You can try writing a wrapper for the command that you wish to execute, one that takes an argument to be used as standard in.  Then use exec() to execute it and capture standard out and the return code.  But don't do this with passwords because the password will be visible to anybody doing a "ps" command.


If you're having trouble creating or modifying files, it's probably a permission problem.  Your code is running as the webserver; a user that has few permissions.

php-doc at tracking.wunsch.org
01-Sep-2000 06:32

Check out the popen function if you want to send data to the standard input of the command you execute, or you want to be able to read its standard output.
holgerlists at blasum dot net
17-Oct-2000 01:29

For anybody confused from a C/Perl background:
PHP's exec() and system() calls really have no relation to what you might expect (replace current process vs.
wait for child process).  PHP's exec($command, $array, $result) thus equals a C-style system().

websites at ANTISPAMkathdesign dot com
02-Apr-2001 03:41

Note that *none* of the Program Executions functions work under Windows 98 using PHP4.0.3pl1 and Personal Web Server. I repeatedly get 'Unable to fork' warnings with no execution of the external calls.
webmaster at jukkis dot net
23-Apr-2001 12:23

Well, now it is possible to put the process to background also on Win98:
I wrote (modified from a ready source :) this little program in C/C++ called bgrun:
www.jukkis.net/bgrun/bgrun.exe or
www.jukkis.net/bgrun/bgrun.cpp

I really have no idea what i was doing when i wrote it, i believe it leaves open the stderr, stdin and stdout (BAD thing..)
but as it works for me (opens winamp without crashing the whole system) I really don't care...

If someone wants to clean up the code, please go ahead.

/jukkis.

ira dot tonert at e-vendo dot de
21-Jun-2001 02: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"

naken at naken dot cc
15-Aug-2001 09:17

Anyone who still wants a copy of mikehup.c,
I rewrote it:  
This program will help you run programs in the
background that are called with the php system()
function.

markie at gnx dot net
22-Aug-2001 12:00

I found a way to get a userlist (users logged in at Novell or NT) into a PHP-script. Because executing commands from PHP seems a lot of trouble i made a bat-file being executed every hour on the server. In the bat-file i put: nlist user /a >> aaa.txt Now, from PHP you can easily read the aaa-file and there you are, all user in your PHP-script!
phobo_AT_paradise.net.nz
04-Sep-2001 02:31

If you're looking for a command to run PHP code from a string, use eval().

This is great for caching semi-dynamic webpages, or to have a .php website with much of it's source in a database...

lk1 at reglos dot de
25-Oct-2001 10: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.

ian at virtisp dot net
16-Jan-2002 10:55

This note is regard php scripts hanging when running system commands in the background until background process completes.  If you have redirected system command output and PHP still waits around until background process completes...check if you are using PHP session handlers.  If you have used a start_session() before your exec() look into session_write_close() ...sessions use files to store session data on ther server to relate to cookies...for some strange reason this open file handler causes PHP scripts to hang until background completetions...I would think only the file handlers for the system command output would need to be delt with but ?!  FreeBSD, Apache mod, PHP 4.1.1
Cheers,
Ian Carlson
[email protected]

edwin at bit dot nl
23-Jan-2002 10: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 [email protected]! :-)

daniel dot hopp at godot dot de
01-Feb-2002 06: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);

----------------------------------------

pvm at nworks dot com
10-Feb-2002 07:09

// If you need to get both the exit status and the return value of
// exec it seems PHP's exec command is broken - at least on my
// system. It does not return the exit status of the process
// reliably, but always -1... Here is a workaround...

// I'm running php v. 4.0.4pl1 on Linux SuSE 7.2 (from command line
// and/or under apache)

// Here is an example of the broken stuff in exec:

// This next should work:
$lines=array();$errco=0;
$result = exec("ls -l /tmp 2>&1",$lines,$errco);
echo "Errco: " . $errco . "\n";
echo "Result: " . $result . "\n\n";

// and this shouldn't (there is no such file as /tm
$lines=array();$errco=0;
$result = exec("ls -l /tm 2>&1",$lines,$errco);
echo "FailErrco: " . $errco . "\n";
echo "FailResult: " . $result . "\n\n";

/*
 This outputs:

Errco: -1
Result: -rw-r--r--    1 root     root         9670 Dec 21 18:27 xwlog

FailErrco: -1
FailResult: ls: /tm: No such file or directory

 And the errco is always -1. From the command line, $? is 0, then 1
 but never -1... Hmm...
*/

// This function returns the status (more) reliably. There are many
// commands that can break it. E.g. if $cmd doesn't finish with a
// newline... If $cmd spawns a process that prints output
// asynchronously (i.e. after the echo $?). There are probably many
// more..  But if you know that command your calling (I wrote mine
// myself), it can work...

// It is called same way as exec...
function myExec($_cmd, &$lines, &$errco) {
 $cmd = "$_cmd ; echo $?";
 exec($cmd, $lines);
 // Get rid of the last errco line...
 $errco = (integer) array_pop($lines);
 if (count($lines) == 0) {
   return "";
 } else {
   return $lines[count($lines) - 1];
}
}

// this should work
$lines=array();$errco=0;
$result = myExec("ls -l /tmp 2>&1",$lines,$errco);
echo "myErrco: " . $errco . "\n";
echo "myResult: " . $result . "\n\n";

// and this shouldn't
$lines=array();$errco=0;
$result = myExec("ls -l /tm 2>&1",$lines,$errco);
echo "myFailErrco: " . $errco . "\n";
echo "myFailResult: " . $result . "\n\n";

/*
 This outputs:

myErrco: 0
myResult: -rw-r--r--    1 root     root         9670 Dec 21 18:27 xwlog

myFailErrco: 1
myFailResult: ls: /tm: No such file or directory

So now I can test for whether a command succeeded or failed... Hope it
helps someone.

*/

marc at million dot nl
10-Feb-2002 07:41

If you try to execute a 16-bit console application on Win95/98, the script hangs.
The solution is to use a 32-bit console application that calls the 16-bit app with the requested parameters, and that will work ok.

The code for such a stub-app can easily be found on the MS site: just Google with '16-bit console windows' and feel lucky :-)
(or try Q150956 directly :)

brendan dot gogarty at utas dot edu dot au--nospam
02-Mar-2002 09:14

windows y2k does work .. just make sure you double backslash everything
eg.

to rotate an image 90 degrees in imagemagic which is in c:\imagemagic
on a file image36.jpg
in f:\wwwroot\web\images\gallery3
you would write

<?
$command="C:\\imagemagick\\convert -rotate 90 f:\\wwwroot\\web\\images\\gallery3\\image36.jpg f:\\\wwwroot\\web\\images\\gallery3\\image36.jpg";

exec("$command");
?>

alan_quill at hotmail dot com
22-Mar-2002 01: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);

vi_pa at hotmail dot com
05-Apr-2002 12: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.

rolland dot dudemaine at msg-software dot com
11-Apr-2002 12: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');
?>

Curt
12-Jun-2002 08:34

if you use session_write_close() in order to exec in the background, you can use session_start() to "turn on" the session again:

session_write_close();
exec(mycommand >/dev/null &);
session_start();

info at businex dot de
17-Jun-2002 12: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 &");

ronnyab at online dot no
22-Jun-2002 01: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"!

deschampsbest at noos dot fr
26-Jun-2002 08: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
");
       }

GCMXZPJPDJER at spammotel dot com
30-Jun-2002 07: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

jeff at jeffglover dot com
01-Jul-2002 11: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 ' -b -O wget-log-1 >&- <&- >/dev/null &");
exec("wget ' -b -O wget-log-2 >&- <&- >/dev/null &");
exec("wget ' -b -O wget-log-3 >&- <&- >/dev/null &");
exec("wget ' -b -O wget-log-4 >&- <&- >/dev/null &");

Good Luck...

ramirosuarez at fibertel dot com dot ar
13-Jul-2002 03: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.

m dot drover at excite dot com
17-Jul-2002 08:12

I have tried all the system() shell_exec, adn exec(), and they all seem to run my in 'in the background'. Is there a way to my app normally. Like so that it take take focus and run like i opened it myself?
shanx at shanx dot com
08-Aug-2002 06: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.

phpmanual at oderwat dot de
10-Aug-2002 08:47

(In addition to an older comment)

I had the requirement to start a program from a php cli-script with a low priority (to run for hours in the background). I found this to be working fine:

$res=exec("start /low /b /wait identify.exe -format \"%w %h %m\" \"".$file."\"");

kop at meme dot com
12-Aug-2002 09: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 &')

thomasdkeller{�t}web{punkt}de
12-Sep-2002 12:33

Finally, after tryin' all your suggestions to get a php script running as background process on a WAMP System (NT) the following code works... (looks ugly, I know, but works, the pipe thing doesn't unfortunately):

exec("start /b mikehup /path/to/php.exe -q dosumthin.php");

k dot mitz dot NO_SPAM at att dot NO_SPAM dot net
15-Sep-2002 09: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!

jseverson at myersinternet dot com
11-Oct-2002 07: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 &");

wusheng at swau dot edu dot cn
21-Nov-2002 07:01

use exec() on win2k and IIS , want to execute WScript.exe to write register. It's strange, the same parameter of exec( ) , can only be execute when refresh another page which contain the exec( ) code, and do nothing when in the pre page. so I create a new page and locate to it .
//---------------------------------------------

<?php
......
......
$cmd="'"."C:\\WINNT\\System32\\WScript.exe C:\\Inetpub\\wwwroot\\ONE.VBS"."'";  
//---- I feel using ' better than using " --//
$openfile=fopen("./REGWRITE.PHP","w+");
$filestr="<"."?php exec($cmd); ?".">";
echo $regstring;
$file_writed=fwrite($openfile,$filestr);
?>

<script>
location.href="REGWRITE.PHP";  //locate to the new page
</script>

//------------------------------------------------

if the code such as below , return no error but do nothing
//------------------------------------------------
<?php
......
......
$cmd="'"."C:\\WINNT\\System32\\WScript.exe C:\\Inetpub\\wwwroot\\ONE.VBS"."'";  
exec($cmd);
?>

NOtvdgeerSPAM at NOxs4allSPAM dot nl
03-Dec-2002 11: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!

krang at krang dot org dot uk
10-Dec-2002 07:15

In reply to...

  ramirosuarez at fibertel dot com dot ar
  12-Jul-2002 09:58

...About the 'Unable to fork' issue.

If anyone has this problem on an IIS server, you can put a copy of 'cmd.exe' (in the windows/system32 folder) into the folder you are executing the 'exec ()' command in.

Although this isn�t really a solution it does work. If anyone can correct me do, but I believe a better method would be to set permissions to use the cmd.exe file - but I�m unsure on how to-do this!

qscripts at lycos dot nl
07-Jan-2003 12: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..

jfl at eksperten dot dk
10-Jan-2003 05: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

jpgiot at ifrance.com
26-Jan-2003 01: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)

goran_johansson at yahoo dot com
19-Feb-2003 12: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.

Marcin Kosieradzki <phantom at acn dot waw dot pl>
06-Mar-2003 01: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`?>

mk at neon1 dot net
20-Apr-2003 04: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.

leenoble at spammenot dot ntlworld dot com
09-May-2003 04: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.

add a note

<pcntl_wtermsigescapeshellarg>
 Last updated: Sat, 19 Apr 2003
show source | credits | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: /
Last updated: Wed May 14 01:12:44 2003 CEST