PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links 
search for in the  
previouspcntl_wtermsigescapeshellargnext
Last updated: Tue, 09 Jul 2002
view the printer friendly version or the printer friendly version with notes or change language to English | Brazilian Portuguese | Chinese | Czech | Dutch | Finnish | German | Hungarian | Italian | Japanese | Korean | Polish | Romanian | Russian | Spanish | Swedish | Turkish

LXXXII. Ex�cution de programmes externes

Ces fonctions fournissent la possibilit� de passer directement des commandes au syst�me, mais aussi de prot�ger le syst�me des commandes pass�es. Ces fonctions sont compl�t�es par l'op�rateur guillemets obliques.

Table des mati�res
escapeshellarg --  Echappe une cha�ne de caract�res pour qu'elle soit utilis�e en ligne de commande.
escapeshellcmd -- Echappe les m�ta-caract�res Shell.
exec -- Ex�cute un programme externe.
passthru --  Ex�cute un programme externe et affiche le r�sultat brut.
proc_close --  Close a process opened by proc_open and return the exit code of that process.
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 --  Ex�cute un programme externe et affiche le r�sultat.
User Contributed Notes
Ex�cution de programmes externes
add a note about notes
[email protected]
04-Jun-1999 10: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 06: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>.

[email protected]
01-Dec-1999 04: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...

[email protected]
22-Jan-2000 11: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 05: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.
[email protected]
17-Oct-2000 12: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().

[email protected]
02-Apr-2001 02: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.
[email protected]
23-Apr-2001 11: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.

[email protected]
21-Jun-2001 01: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"

[email protected]
15-Aug-2001 08: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.

[email protected]
22-Aug-2001 11: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 01: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...

[email protected]
25-Oct-2001 09: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.

[email protected]
16-Jan-2002 09: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]

[email protected]
23-Jan-2002 09: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]! :-)

[email protected]
01-Feb-2002 05: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);

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

[email protected]
10-Feb-2002 06: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.

*/

[email protected]
10-Feb-2002 06: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 :)

[email protected]
02-Mar-2002 08: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");
?>

[email protected]
22-Mar-2002 12: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);

[email protected]
05-Apr-2002 11: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.

[email protected]
11-Apr-2002 11: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 07: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();

[email protected]
17-Jun-2002 11: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 &");

[email protected]
22-Jun-2002 12: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"!

[email protected]
26-Jun-2002 07:03

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
");
}

[email protected]
26-Jun-2002 07: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
");
}

[email protected]
30-Jun-2002 06: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

[email protected]
01-Jul-2002 10: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...

[email protected]
13-Jul-2002 02: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.

[email protected]
17-Jul-2002 07: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?
[email protected]
08-Aug-2002 05: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.

[email protected]
10-Aug-2002 07: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."\"");

[email protected]
12-Aug-2002 08: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 &')

add a note about notes
previouspcntl_wtermsigescapeshellargnext
Last updated: Tue, 09 Jul 2002
show source | credits | stats | mirror sites
Copyright © 2001, 2002 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Sat Aug 31 06:19:44 2002 CEST