★ wanayoo — archive 1999 http://fr.php.net/manual/fr/function.exec.phpNouvelle recherche | Portail wanayoo
PHP  
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links 
search for in the  
<escapeshellcmdpassthru>
view the version of this page
Last updated: Wed, 15 Jan 2003

exec

(PHP 3, PHP 4 )

exec -- Exécute un programme externe.

Description

string exec ( string command [, string array [, int return_var]])

exec() éxecute la commande command, mais ne renvoie rien comme retour, hormis la dernière ligne du résultat de la commande. Pour exécuter une commande et obtenir le résultat sans aucun traitement, il faut utiliser la fonction passthru().

Si l'argument array est présent, alors ce tableau sera rempli par les lignes retournées par la commande. Il faut noter que si ce tableau contient des éléments, exec() ajoutera les nouvelles lignes à la fin du tableau. Si vous ne voulez pas que les nouveaux éléments soient concaténés, utilisez la fonction unset() avec ce tableau avant de le passer à exec().

Si l'argument return_var est présent en plus du tableau array, alors de statut de retour d'exécution sera inscrit dans cette variable.

Notez que si vous allez fournir des commandes qui proviennent d'un utilisateur, il est avisé d'utiliser la fonction escapeshellcmd() pour s'assurer que l'utilisateur n'essaie pas de profiter des caractères spéciaux pour tromper le système.

Voir aussi system(), passthru(), popen(), escapeshellcmd(), et les opérateurs guillemets obliques.

User Contributed Notes
exec
add a note about notes
landon at bradshaw dot org
29-Jul-1999 12:30

<i>STDERR</i> is not handled and any output to will be passed to the browser as part of the page.


To stop this from happening you can append '2>&1' on the end of your command-line to redirect STDERR to STDOUT.


sam at netexposure dot com dot au
08-Jul-2000 12:17

After scanning through <pre>php-4.0.1pl2/ext/standard/exec.c</pre> and guessing a bit, I discovered that shell_exec can be used like this:

<pre>
$zipfile=shell_exec("zip -r - ./backups/");
</pre>

I found this useful when exec() didn't work the way I expected it to.

dogwild at gmx dot ch
21-Jul-2000 11:08

To all those who had problems with calling perl-scripts from php. i used the passthru method like this:
passthru("perl /absolutepath/script.pl scriptparameter");
in the perl-script you have to read the parameters out of the @argv variable.

jjchristian at mail dot com
26-Aug-2000 08:24

I found it useful to exec a perl script while continuing executing the php code (if the perl script takes a while to execute and the php code doesnt need it to keep processing...)

exec('perl perscript.pl > /dev/null');

obvious, but handy to know...

tcurdt at dff dot st
19-Nov-2000 05:38

If you want to run commands not only from the "safe_mode_exec_dir" set "safe_mode" to "Off" in the php.ini.
(e.g. running ispell from within IMP)

prices at dflytech dot com
05-Dec-2000 02:36

This may seem obvious, but to run a command and not wait for its output you have to put the command in the background.  This means in *nix you have to append a '&' on the end of the command like:

exec("command &");

Scott  =)

ik at avatartech dot com
09-Jan-2001 11:40

Don't believe the documentation. You should be using escapeShellArg, not escapeShellCmd most of the time. If you don't have php4.0.3 or better, read the comments under escapeShellCmd to find an equivalent replacement function.
bvr at xs4all dot nl
17-Jan-2001 07:43

I just discovered that you can also execute a command by
place the command string between ` characters. This simply
evaluates to the output of the command.

example:
&lt;? $foo = `ls -al /`;
  echo($foo);
?>

jase at sensis dot com
30-Jan-2001 10:18

When I compiled php with "--enable-sigchild", all calls to exec set return_var to -1. When I recompiled without "--enable-sigchild", all calles to exec set return_var to the expected value.

I hope that maybe this helps someone.

pabasoftware at yahoo dot com
12-Feb-2001 01:10

I found that if you want to execute something in background, you have to use *both* & and >/dev/null. Maybe this is true only in some special situations, anyway my perl script wasn't executed in background until I did this:
exec("myperlscript.pl parameters >/dev/null &");
Btw: refers to php3 on a Linux system.

bens_nospam at benjamindsmith dot com
15-Feb-2001 08:19

ON A LINUX SYSTEM:

Note that the exec() function calls the program DIRECTLY without any intermediate shell. Compare this with the backtick operator that executes a shell which then calls the program you ask for.

This makes the most difference when you are trying to pass complex variables to the program you are trying to execute - the shell can interpret your parameters before passing them thru to the program being called - making a dog's breakfast of your input stream.

Remember: exec() calls the program DIRECTLY - the backtick (and, I THINK, the system() call) execute the program thru a shell.

-Ben

kaysb at uten dot net
18-Feb-2001 07:18

to execute a command and put it to the back is a dangerous thing to do. imagen the work load if a person is reloading the script rapetly. or if 500 persons run it at the same time (lage sites)... insted, make a cron job or something to do the work. (sorry about my poor english;)
pkshifted at slackin dot com
07-Mar-2001 06:24

If you want to use exec() to start a program in the background, and aren't worried about load (because the program can only run one instance or you will manually stop it before starting it again) you can use either of these methods to leave it running in the background indefinately.

Add set_time_limit(some ridiculously huge number) to your script, cause even though it won't stop it, it does seem to allow it to run longer than usual.
...or...
exec("nohup *command* 1>/dev/null/ 2>&1 &");

Thanks to the guys on the php list for helping me solve this unusual(?) problem.

marat at provote dot com
13-Apr-2001 10:22

After agonizing over the seemingly simple question of how to pass back a string value from a PERL script to a PHP script, trying the system, and passthru functions, as well as backticks, proved futile. However this wonderful exec function is the answer. It's terribly simple:

If you want to return any number of scalars from your PERL script to PHP, then print them to stdout at the end of your PERL, as in:

<pre>
print $scalar1 ;
print $scalar2 ;
print $scalar3 ;
</pre>

Then, on the PHP side, you simply declare:

<pre>
exec("path_to_perl_file", $array)
</pre>

Now you just loop through $array, to grab the scalars output by your PERL script... Enjoy, hope this helps someone...

auriane at bigfoot dot com
12-May-2001 09:10

If you want to use the exec command to change passwords in a .htaccess file, it's possible, but do not use the direct exec command, that didn't work for me.

What works perfectly; (on Linux)
$Htuserfile = "/home/userssite";
$Pathhtpasswd = "/usr/local/apache/bin/htpasswd -b";
$test=shell_exec($Pathhtpasswd." ".$Htuserfile." ".strtolower($Login_Name)." $Password");

csaba at alum dot mit dot edu
22-May-2001 01:18

On Win98, the exec, backticks, etc. have given me a lot of trouble.
Please see the May 2001 archives of the PHP mailing list within the
CURL site ( http://curl.haxx.se/mail/curlphp-2001-05/0028.html ) for how I solved Exec-ing problems (basically, I use Excel's Shell command, and
have it do the shelling for me), including an asychronous exec of
another .php file (for which I use CURL to call the .php file).

andrei at ucar dot edu
06-Jun-2001 08:38

Thanks to marat@provote.com who submitted a note about passing parameters from perl script back to php script with "exec". "exec" works just fine if you need to execute perl script from your php code once in a while. But if you want to optimize perl performance, you want to run it under mod_perl, right? You can use "fopen" in this case.

The perl script runs under mod_perl and just prints out the variables it wants to pass to php script:
#!/usr/local/bin/perl -w
use strict;
use CGI qw(-compile :all);
my $q = CGI->new();
print($q->header());
print "It worked!!!\n";
if(exists $ENV{MOD_PERL}) {
  print "we're running under mod_perl\n";
}
else {
  print "we're NOT running under mod_perl\n";
}
print "parameter1\n";
print "parameter2";

PHP script just calls this script with fopen and uses fgets to retrieve the output:
$fp = fopen ("http://your.website.com/perl/perlscript.pl", "r");
$i=0;
while (!feof($fp)) {
      ${"par$i"} = fgets ($fp,4096);
       echo "parameter $i: ${"par$i"}";
       $i++;
}

ary at communicationfactory dot com
13-Jun-2001 11:10

Remember to use unix exit(o); on unix calls that use Unix redirection operator ">" . This was a real problem for me, I was not getting a response back in the following code until I added exit(0);

<?PHP
function myspawn()
{
$command="/usr/local/bin/mybinary infile.txt > outfile.tx2";
exec($command);
## nothing worked for me until I added this next line.
exec("exit(0)");
}
?>
<html>
<head>
<title>New Page 1</title>
</head>
<body>
Creating output file now
<? myspawn();?>
</body>
</html>

a dot henss at web dot de
29-Jun-2001 12:18

Under Windows NT you can retrieve a Tasklist with this script!

<?php
if(getenv("OS")!="Windows_NT")
{
 echo "This script runs only under Windows NT";
}
$tlist1 = shell_exec("cmd /c tlist.exe");
$tlist2 = ereg_replace(" ","&nbsp;",$tlist1);
$tlist = nl2br($tlist2);
echo "<font face=\"Fixedsys\">\n";
echo $tlist;
echo "</font>";
?>

ryan at imagesmith dot com
17-Jul-2001 10:47

Some sites provide an htpasswd program that doesn't allow the -b switch (i.e. batch adding).  
 So I've used this to add a user.  (This is all one line of code.  Sorry it looks so intense here).

system("perl -e \"print \\\"$UserName:\\\" . crypt('$Password', join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]) . \\\"\\n\\\";\" >> $path_to_pass_file");

yong-q at cosix dot com dot cn
02-Aug-2001 03:36

i want to execute print.out to return the output to $res,but it is empty.
print.c:
        main()
              {printf("it is test" )}
test.php:
        <?
        $res=exec(print.out);
          echo $res;

$PATH=..........:/tmp/;export $PATH

test.php:
       <?
          $res=exec("ls /home");
         echo $res;
        ?>
result:/usr

why?

chungdownload at hotmail dot com
05-Aug-2001 06:42

For Win2k
   If you are using php-4.0.6 and receive an err msg of "unable to fork ..." after running "exec("echo 1")", you can do the followings:
1) Download the CVS version at snaps.php.net
or
2) use "exec("cmd /c echo 1")

This bug was reported a year ago, but is somehow not fixed in http://gtk.php.net/download.php.

cybo at tokyo dot com
17-Aug-2001 12:47

Comment to the above hint by "chungdownload@hotmail.com":
[W2K]:
If you use option 2), the output won't be saved in the optional string.
For example:"exec("cmd /c dir", $dir_result);
$dir_result will be empty.
However, this works:
$dir_result=system("cmd /c dir");  

Hm.. seems PHP crashes when a exe-file is tried to be launched. Only restarting Apache can help then.

Yannis dot BRES at cma dot inria dot fr
07-Sep-2001 07:30

It seems that exec first launches a shell (command processor) under Linux, but not under Windows.  Therefore, redirection tricks like 2>&1 do not work under Windows.  In order to force the launching of an executable through a command processor under Windows, and be able to use redirection, prepend getenv( "COMSPEC" ) . " /C " to the name of your executable.
jeff at iomojo dot com
11-Sep-2001 06:53

When executing a program in the background AND using sessions, subsequent clicks in the browser won't do anything until after the background process finishes.  Even though control is returned to the browser, all clicks will hang.


To get around this, here's what I did:


<?
session_start();
$userid = $HTTP_SESSION_VARS["userid"];

//... assign $command to the command to execute

exec("$command >/dev/null &");
session_unregister("userid");
session_destroy();
session_start();
session_register("userid");

// rest of script.
?>


It's a hack because you get a new session id, but if you can live with that, it may be of some help.


Note:  This is 4.06 / apache 1.3.20 / linux

drillo70 at yahoo dot com
19-Dec-2001 08:12

To get around the problem arising from sessions and background program execution (with system, exec or passthru) you can do this:

.....
session_write_close();
$dummy = system("./run &", $code);
.....

NOTE: remember to set all your session registered variables before you call session_write_close()! see session_write_close() manual page for details.

robsnc at excite dot com
10-Jan-2002 05:14

For 'unable to fork' errors, keep in mind that, in Windows, the new process doesn't know the paths to your executables.  For example, you may have PERL in you PATH statement, but if you 'exec' a PERL script without providing the full path to the PERL program, your PHP script won't know how to handle the PERL script.

This will return an error:
exec("myperlscript.pl");

Correct format:
exec("C:\perl\perl.exe c:\www\myperlscript.pl");

11-Jan-2002 12:39
When using escapeshellcmd and the stderr to stdout redirect '2>&1'. Append '2>&1' to the call to escapeshellcmd not within it, otherwise the returning string is empty rather than containing the error.

$cmd = escapeshellcmd("...")." 2>&1";
$string = exec($cmd,$array,$integer);

hans at internit dot NO_SPAM dot com
02-Feb-2002 09:25

From what I've gathered asking around, there is no way to pass back a perl array into a php script using the exec function.

The suggestion is to just print out your perl array variables at the end of your script, and then grabbing each array member from the array returned by the exec function. If you will be passing multiple arrays, or if you need to keep track of array keys as well as values, then as you print each array or hash variable at the end of your perl script, you should concatenate the value with the key and array name, using an underscore, as in:

foreach (@array) print "(array name)_(member_key)_($_)" ;

Then you would simply iterate through the array returned by the exec function, and split each variable along the underscore.

Here I like to especially thank Marat for the knowledge. Hope this is useful to others in search for similar answer!

marat at provote dot com
14-Feb-2002 02:58

As we all know, there are often times more ways than one to skin a cat.

The example above is universal in that the logic which supports it would work no matter how many arrays or hashes you needed to pass back to your PHP script, from the PERL script the PHP executed.

However, if you were passing back strictly arrays, then you might want to try something a little more effecient, which would not require a 'foreach()' loop to produce the output on the PERL side.

Passing back one or more arrays in PERL:

<code>
print "\"" . @array . "\" \"(array name)\" @(array name)" ;
</code>

This will produce a 'double-quote space double-quote' delimited string of array values. The first value in this string will be the number of members in the PERL array, while the second value is the name of the PERL array. This member number value becomes important on the PHP side, when we want to do a cursory consistency check on the PHP array.

Grabbing output PERL arrays in PHP:

<code>
exec("path_to_perl_file", $array) ;

while (list($name, $value) = each($array)) {
   $temparray = split('" "', $value) ;
   $perlarraylength = $temparray[0] ;
   $perlarrayname = $temparray[1] ;
   unset($temparray[0]) ;
   unset($temparray[1]) ;

   /* here is where the consistency check comes in */

   if ($perlarraylength != sizeof($temparray)) {
      echo("corrupt perl to php array translation...") ;}

   else { ${$perlarrayname} = $temparray ;}
   unset($temparray) ;}
</code>

That's it..., quick and easy.

Unfortunately, PERL hashes can't be handled in this fashion, seeing as how simply printing "%(hash name)" will yield the hex reference to the hash. Therefore PERL hashes must be passed back by printing each member through a loop...

Needed to clarify,
MARAT

sam at nova-mag dot org
12-Mar-2002 05:54

if you wanna execute a perl-script and grab the ouput (as for perl fortune auto-selection), you can use the following :

exec("perl script.pl [args]", $out);
for ($i = 0 ; $i < count ($out) ; $i++)
 echo "$out[$i]\n";

excuse my english, but i'm french :)

27-Mar-2002 04:49
RE: Executing Perl scripts from PHP...

Things to check if your perl scripts won't execute from PHP:

1) Is the Perl script owned and executable by the Apache user? (wwwrun, for example)

2) Did you specify the full path the the perl script when you passed it to exec(), shell_exec(), etc?

27-Mar-2002 05:01
Almost killed myself over this one!

I kept getting "text file busy" errors in the Apache log (not PHP log) when executing Perl scripts from PHP.

I did some research and found this can be caused by having the file in use by Samba. I was editing on my Windoze box, leaving the file open in my editor, and then previewing the result in a browser.

As soon as I stopped accessing the Perl file through Samba (i.e. closing my editor, not displaying the file in Windoze Explorer), the problem disappeared.

I was sure I had some sort of permissions problem, or wasn't closing a file, or something. But Samba appeared to be the culprit.

FYI, Samba was writing as root, which DID cause a permissions issue, but I caught that early on and it didn't solve the "text file busy" error.

Someone please berate me if this seems nuts...

brianw at gdinet dot com
02-May-2002 09:46

Has anyone had any luck in getting exec, shell_exec, backticks, system, etc working for opening an ssh session to and running a command on a remote machine?

I kepp seeing the PHP web server close the session before authentication is complete.

Running the exact same command manually works just fine.

Here's my command:
ssh -l root myserver.mydomain.com /usr/local/pwdchange username newpassword oldpassword

I can run other shell commands just fine.

Thank's
BEW

me at jcornelius dot com
15-May-2002 05:06

Note that when in 'Safe Mode' you must have the script or program you are trying to execute in the 'safe_mode_exec_dir'. You can find out what this directory is by using phpinfo().
phpnet at chris-decker dot com
24-May-2002 05:25

The gist of what I'm trying to do:

Make a form that requires the user to input an IP address.  Then it executes NMap on that particular IP addresss.  Can anyone help me out with this?

opuzer at msn dot com
24-May-2002 06:05

on win32 with apahce2 and latest php , i have interact with desktop set to true on the apache service, when i execute an external program it shows up on my desktop, how can i stop this, this behavior just started showing up with the new build of apache and php

and i need the interact so i can grab winamps title

walidn at yahoo dot com
28-Jun-2002 02:28

I'm using mod_php4 on apache2 installed on freebsd 4.6.

function traf_b($id){
$ipfw_ar = "add 100 pass ip from any to 192.168.1.100 via rl1 in ";
$lastline = exec("/sbin/ipfw $ipfw_ar",$allout, $return);}

I couldnt execute 'ipfw '.
but executing 'ls -lo' or 'ps awx' works fine. What might be the problem.
P.S i also used shell_exec,backtrick but the result was negative . /safe_mod is off

nicos at php dot net
29-Jun-2002 06:32

For those who've got a problem with running a background process with exec(), it looks that some process doesn't support it at all, some will need to be redirected to /dev/null. If you can't load your program even with ">/dev/null" you are supposed to code a little sh script to run your program in background
This is 'file.sh'
#/bin/sh
command_here &
and you :
exec("file.sh");

Note: this will not work with the program that require an output on your screen like 'top'.
Have fun - Nicos

kop at meme dot com
08-Jul-2002 09:19

Nowhere is it mentioned that exec() strips off the end-of-line character(s) from the command's output.  This is true both in the return value and in the values assigned to the array in the second argument.

This makes it impossible to tell if the command output ends in a end-of-line character(s).

blackwolfsystems at yahoo dot com
17-Jul-2002 03:24

I have found that when you run a perl script in the background under linux, you have to use >&- <&- otherwise it waits until the script has finished before continuing.  This wouldn't be so bad except that if the perl script you are executing wants to read or write to a file it doesn't seem to be able to after this.
b dot basse at home dot se
24-Jul-2002 01:44

Under Windows XP you can retrieve a Tasklist with this script!
<?php
$tlist1 = shell_exec("cmd /c tasklist");
$tlist2 = ereg_replace(" ","&nbsp;",$tlist1);
$tlist = nl2br($tlist2);
echo "<font face=\"Fixedsys\">\n";
echo $tlist;
echo "</font>";
?>

mightye at mightye dot org
29-Jul-2002 07:32

PHP pages will still hang waiting on exec()'d processes to finish before the server sends eof to the browser, at least with php4.1.2 on apache 1.3.24.  I'm trying to create a web-based interface to a MP3 player using mpg123.  I exec("mpg123 -v \"$HTTP_GET_VARS[item]\" > /tmp/mpg123status 2>&1 &");, and the rest of my script executes fine, but at the exit(); or end of the script, the browser just sits there holding its page until the mpg123 status either finishes on its own, or is terminated.  As under my setup, that means no further requests will be fulfilled to the php script that is still hanging, this becomes a problem.

I haven't been able to identify a means to allow the script to terminate, yet allow the sub process (mpg123) to continue, has anyone had luck obtaining this sort of result?  Halting the script via stop in the browser, or terminating on the command line allows the mpg123 process to continue, and further requests for my php script to be honored.

ronperrella at NOSPAM dot hotmail dot com
06-Aug-2002 06:04

I ran into the problem of not being able to set environment variables for my kornshell scripts. In other words, I could not use putenv() (at least to my understanding).

The solution I used was to write a script on the fly, then execute that script using exec().

$prgfile = tempnam("/tmp", "SH");
chmod($prgfile, 0755);
$fp = fopen($prgfile, "w");
fwrite($fp, "#!/bin/ksh\n");
fwrite($fp, "export MYENV=MYVALUE\n");
fwrite($fp, "ls -l\n"); // or whatever you wanna run
fclose($fp);
exec($prgfile, $output, $rc);

then delete the temp file (I keep it around for debugging.)

iceburn at dangerzone dot c o m
10-Sep-2002 12:20

This seems to work for me on win2k server w/ iis 5  w/ php 4.2.2....

<?php
if(getenv("OS")!="Windows_NT")
{
 echo "This script runs only under Windows NT";
}

$tmp = exec("usrstat.exe Domain", $results);

foreach ($ping_results as $row) echo $row . "
";
echo "done";
?>

For those that don't know what usrstat is, it's a program that is the admin pack for win2k that lists users in a domain and thier last logon time.  I used it as the example to show that arguments can be passed (the domain).

The one "gotcha" is that usrstat.exe must be in the system path...ie if you are at the server w/ a command window, anything you can type w/o typing in a path, works.  Try it with ping, since that should be in system32 for just about everyone...

I've tried things like:
exec("c:\temp\usrstatexe...
exec("cmd /c c:\temp\usrstat.exe...

but can't seem to get anywhere with those...

even putting the exe on a shared drive with identical paths for the client and server to the exe doesn't work (don't know why that would fix it, but was just trying things...)

25-Sep-2002 09:25
I found that if exec took longer than 30 seconds to complete, it would fail with an error code of 155 and the process would be killed.  The solution to this problem is to set_time_limit() to a reasonable value.
karl at cactuslab dot com
22-Oct-2002 08:27

Regarding the question from mightye at mightye dot org about exec leaving programs running in the background causing PHP to lock up - at least for your current session.

I think this is due to the locking of session data? Try adding a session_write_close() before your exec and see if that fixes it. Fixed it for me.

mimnermo00 at hotmail dot com
17-Jan-2003 02:47

Hi all,
i hope this is anybody useful.
This simple script gives an output shell error if an error occurr in command placed in exec.
= )
Carlitos

<?
#############
// $command="pwd";  //  <--- this produces no uotput

$command="ls -lazse";  //(bad command )<--- this produces, instead
// an error in uotput
#############
$command_null="$command>/dev/null";
echo "<h2>ERROR FROM EXEC</h2>
$str
";
$str=exec($command_null,$arr,$err);
$std_err="2>&1";
if ($err!=0){
echo "error:
";
$str=exec("$command $std_err",$arr,$err);
echo "$str
";
}

?>

Rx
06-Feb-2003 11:41

If you have SUEXEC enabled, only the exec() function works with suexec support.
marc at thewebguys dot com dot au
26-Feb-2003 02:51

I wrote a simple ping user function, useful for automatically determining wether to show high bandwidth content or calculating download times.

function PingUser() {
 global $REMOTE_ADDR;
 return ereg_replace(" ms","",end(explode("/",exec("ping -q -c 1 $REMOTE_ADDR"))));
 }

It returns a number representing the milli seconds it took to send and receive packets from the user.

add a note about notes

<escapeshellcmdpassthru>
 Last updated: Wed, 15 Jan 2003
show source | credits | stats | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: nexen.net
Last updated: Sun Mar 16 04:12:42 2003 CET