PHP  
downloads | documentation | faq | getting help | | php.net sites | links 
search for in the  
previouspcntl_wtermsigescapeshellargnext
Last updated: Tue, 28 May 2002
view this page in Printer friendly version | English | Brazilian Portuguese | Czech | Dutch | French | German | Hungarian | Italian | Japanese | Korean | Polish | Romanian | Russian | Spanish | Turkish

LXXXI. Program Execution functions

Introduction

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

Requirements

These functions are available as part of the standard module, which is always available.

Installation

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

Runtime Configuration

T�m� laajennus ei m��rittele yht�k��n konfigurointi asetusta.

Resource Types

T�m� laajennus ei m��rittele yht�k��n resurssi-tyyppi�.

Predefined Constants

T�m� laajennus ei m��rittele yht�k��n vakiota.

See Also

Those functions are also closely related to the backtick operator.

Sis�llys
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_open --  Execute a command and open file pointers for input/output
shell_exec --  Execute command via shell and return complete output as string
system -- Execute an external program and display output
User Contributed Notes
Program Execution functions
add a note about notes

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>.



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...


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.


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().


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.


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.


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"


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.


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...


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.


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]


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]! :-)


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

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


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.

*/


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 :)


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


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


04-Apr-2002 04:44

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. Any insight into this?


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.


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();


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


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"!


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


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


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


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...

add a note about notes
previouspcntl_wtermsigescapeshellargnext
Last updated: Tue, 28 May 2002
show source | credits | stats | mirror sites:  
Copyright © 2001, 2002 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Thu Jul 4 12:06:15 2002 CEST