Program execution 函数
在线手册:中文  英文

exec

(PHP 4, PHP 5)

execExecute an external program

说明

string exec ( string $command [, array &$output [, int &$return_var ]] )

exec() executes the given command.

参数

command

The command that will be executed.

output

If the output argument is present, then the specified array will be filled with every line of output from the command. Trailing whitespace, such as \n, is not included in this array. Note that if the array already contains some elements, exec() will append to the end of the array. If you do not want the function to append elements, call unset() on the array before passing it to exec().

return_var

If the return_var argument is present along with the output argument, then the return status of the executed command will be written to this variable.

返回值

The last line from the result of the command. If you need to execute a command and have all the data from the command passed directly back without any interference, use the passthru() function.

To get the output of the executed command, be sure to set and use the output parameter.

范例

Example #1 An exec() example

<?php
// outputs the username that owns the running php/httpd process
// (on a system with the "whoami" executable in the path)
echo exec('whoami');
?>

注释

Warning

当用户提供的数据传入此函数,使用 escapeshellarg()escapeshellcmd() 来确保用户欺骗系统从而执行任意命令。

Note:

如何程序使用此函数启动,为了能保持在后台运行,此程序必须将输出重定向到文件或其它输出流。否则会导致 PHP 挂起,直至程序执行结束。

Note: 安全模式 启用时,可仅可用 safe_mode_exec_dir 执行文件。实际上,现在不允许在到可执行的路径中存在 .. 组件。

Warning

安全模式 启用时,命令字符串会被 escapeshellcmd() 转换。因此,echo y | echo x 会变成 echo y \| echo x

参见


Program execution 函数
在线手册:中文  英文

用户评论:

Alonso Castro (2013-07-04 17:15:34)

hello I have a problem for the generation of image thumbnails pluguin through the video embed and thumbnail generator, when I want to enable thumbnail image I get the following message:

"EXEC PHP is disabled in settings. You can embed existing video, but video thumbnail generation and Mobile/HTML5 video encoding will not work. Contact your System Administrator to find out if you can enable EXEC"
I spoke with the creator of the plugin and I said:
"Just like the error message says, your server has the EXEC PHP function disabled. Sometimes EXEC is disabled for security reasons and cannot be enabled. I have no ability to tell you how to enable EXEC on your server because I don’t know why it is disabled. If you can enable EXEC and you have FFMPEG installed on your server then you can make thumbnails. Most shared hosts don’t allow you to install FFMPEG".
Any idea or solution to fix this problem, because what I want is to embed video but leaving the thumbnails.
Pdta: I am new to this topic so I would appreciate if I explained in detail.
thanks for the prompt RPTA

jtkremer at yahoo dot com (2013-04-07 15:25:33)

Run a DOS command and parse it for specific lines

<?php

$i 
0;
exec('ipconfig /all'$response);
foreach(
$response as $line) {
  
  
$line $line;
  
  if (
strpos($line"DNS")>0) {
    print (
trim($line));
    echo (
"\n");
    }
}

?>

sprunka at gmail dot com (2012-12-19 20:01:26)

exec($cmd . " &") did not seem to work for backgrounding a task in linux, but using the pclose(popen($cmd . ' &', 'r')); trick from the Windows advice did work just fine.
This is, of course, without catching and throwing away or catching and saving any output (stdout or stderr) from $cmd.

Matthias Marx (2012-11-13 21:46:21)

I had a script calling a powershell script in one function. It worked fine on XP but when we moved to Windows 7 it stopped working. The script seemed to hang and expect a carriage return before it continued.

Adding "echo . |" before calling powershell gave it the desired carriage return:

<?php
exec 
"powershell.exe someScript.ps1" ); // hangs 
exec "echo . | powershell.exe someScript.ps1 " ); // works
?>

wouter99999 at gmail dot com (2012-09-22 20:52:20)

To run your command in the background on Windows, you have to use start /B before your command (in Linux add & after your command). exec() simply uses cmd /C. The /C carries out the command specified by the string and then terminates.
However start /B needs to be put before that, so you cannot use exec() for running a command in the background on Windows. Instead use popen. Example: pclose(popen('start /B php yourscript.php > result.txt 2> error.log', 'r')); works.
But what if you have spaces in your filenames? Escape them with double quotes:
pclose(popen('start /B php "your script.php" > "my result.txt" 2> "error.log"' , 'r')); works.
But now let's assume that you do not have php in your path. This does not work:
pclose(popen('start /B "C:\Program Files (x86)\PHP\php.exe" "your script.php" > "my result.txt" 2> "error.log"' , 'r'));
Why? Because cmd only preserves the double quotes if there is not one of: &<>()@^| special characters between the two double-quote characters.
Double quotes between double quotes are preserved however if /S is used, in that case only the two outer double quotes are removed. So add two double quotes surrounding your command and add the default cmd /C plus the extra /S like:
pclose(popen('start /B cmd /S /C ""C:\Program Files (x86)\PHP\php.exe" "your script.php" > "my result.txt" 2> "error.log""' , 'r'));

cristian dot gabbanini at gmail dot com (2012-03-26 18:56:34)

In case you need to sequentially execute multiple commands, it is useful to do something like the following instead of launching multiple times the exec function:

<?php

    $cmd 
name of the command to be executed;

    
$array = array containing values to cycle;

    
$s sizeof($array);

    
$commandString '';

    while(
$s--){

        
//Here you should perfomr any needed operation
        
$commandString .= "$cmd;";

    }

    
exec($commandString);

?>

IanB (2012-02-10 13:24:41)

As already noted by others, to background a single command on Linux append the & symbol.

For a sequence of commands, enclose them within parentheses then append the & symbol but be sure to redirect stdout, stderr somewhere otherwise your script will hang waiting e.g.:

<?php

exec
('( sleep 10; echo "finished" | mail ian@example.com ) &> /dev/null &');

?>

Usually you would put the commands in a shell script and call that from exec, however the above trick will help where the sequence is dynamically generated from php.

Credit to http://stackoverflow.com/a/3750028 for the idea.

mail at samtuke dot com (2011-05-16 08:52:35)

There are (perhaps insurmountable) difficulties when trying to execute sudo commands from a PHP script and from an external script called by PHP on SELinux enabled machines.
SELinux won't let apache change the group id of the process by default.
You may need to use another solution, like make the PHP script deposit a file in a directory which is monitored by cron or inotify and which will call another script with root privileges.

abaker (2011-04-19 10:47:34)

If you try to run an application from C:\Windows\System32 from a 32 bit install of PHP on 64 bit Windows, and the application doesn't have a 32bit version in C:\Windows\SysWOW64, you can use C:\Windows\Sysnative instead to reference the actual System32 folder rather than the redirected one in SysWOW64.

bmellink at hotmail dot com (2011-02-09 12:02:20)

When calling exec() from within an apache php script, make sure to take care of stdout, stderr and stdin (as in the example below). If you forget this and your shell command produces output the sh and apache deamons may never return (they will normally time out after a few minutes). From the calling web page the script may seem to not return any data.
If you want to start a php process that continues to run independently from apache (with a different parent pid) use nohub. Example:
exec('nohup php process.php > process.out 2> process.err < /dev/null &');

juan at laluca dot com (2011-01-13 07:36:06)

I was trying to get an acceslist from a remote computer by executing cacls and parse it in php, all in a  Windows environment with Apache. First i discovered psexec.exe from Windows SysInternals.

But with the following line, I didn?t get anything, it get hunged, although from the command line it worked nice:

<?php exec ('c:\\WINDOWS\\system32\\psexec.exe \\192.168.1.224 -u myuser -p mypassword -accepteula cacls c:\\documents\\RRHH && exit'$arrACL ); ?>

To make it work I just followed the next steps:
- execute services.msc and find the apache service (In my case wampapache)
- Right button>Log On tab and change from Local System Account to a user created account, enter the username and the password and restart the service.

(I added this user to the administrators group to avoid permissions problems but its not recommended...)

It worked! And it may work with IIS too so try it if you have the same poblem....

Hope this helps someone, and sorry for my english

vaflancher at gmail dot com (2011-01-08 00:59:09)

Here is I written a function, that shows the ping on the OS Windows and Linux, helps me a lot, shows players theirs ping to the server (the site is where the server).

<?php
function GetPing($ip=NULL) {
 if(empty(
$ip)) {$ip $_SERVER['REMOTE_ADDR'];}
 if(
getenv("OS")=="Windows_NT") {
  
$exec exec("ping -n 3 -l 64 ".$ip);
  return 
end(explode(" "$exec ));
 }
 else {
  
$exec exec("ping -c 3 -s 64 -t 64 ".$ip);
  
$array explode("/"end(explode("="$exec )) );
  return 
ceil($array[1]) . 'ms';
 }
}

echo 
GetPing();
?>

alvaro at demogracia dot com (2010-12-27 05:27:01)

In Windows, exec() issues an internal call to "cmd /c your_command". This implies that your command must follow the rules imposed by cmd.exe which includes an extra set of quotes around the full command:
- http://ss64.com/nt/cmd.html
Current PHP versions take this into account and add the quotes automatically, but old versions didn't.
Apparently, the change was made in PHP/5.3.0 yet not backported to 5.2.x because it's a backwards incompatible change. To sum up:
- In PHP/5.2 and older you have to surround the full command plus arguments in double quotes
- In PHP/5.3 and greater you don't have to (if you do, your script will break)
If you are interested in the internals, this is the source code:
sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command);
It can be found at http://svn.php.net/viewvc/ (please find php/php-src/trunk/TSRM/tsrm_win32.c, the comment system doesn't allow the direct link).

Martin Lakes (2010-12-21 08:20:39)

Took quite some time to figure out the line I am going to post next. If you want to execute a command in the background without having the script waiting for the result, you can do the following:

<?php
passthru
("/usr/bin/php /path/to/script.php ".$argv_parameter." >> /path/to/log_file.log 2>&1 &");
?>

There are a few thing that are important here. 

First of all: put the full path to the php binary, because this command will run under the apache user, and you will probably not have command alias like php set in that user.

Seccond: Note 2 things at the end of the command string: the '2>&1' and the '&'. The '2>&1' is for redirecting errors to the standard IO. And the most important thing is the '&' at the end of the command string, which tells the terminal not to wait for a response.

Third: Make sure you have 777 permissions on the 'log_file.log' file

Enojy!

ben-sky at netcourrier dot com (2010-10-05 04:29:22)

The output parameter gets only standard output, if you need error output too, don't forget to redirect it. 
If the output parameter is still empty after an execution and if it shouldn't, you must be in this case.

<?php
$out 
= array();
exec = ('ls /ver 2>&1'$out);
print_r($out);
?>

digitalaudiorock at gmail dot com (2010-09-17 07:34:12)

Just a note related to exec() and programs that run in the background.  I have a service that backgrounds itself using the Pear System_Daemon (whose start method forks the process and closes the parent).  When I attempted to start that using the services /etc/init.d/service_name start from within another php script using exec(), I expected it to work without redirecting output, but it still hung unless I did.

That solution is to close STDOUT and STDERR:

<?php
if (is_resource(STDOUT)) fclose(STDOUT);
if (
is_resource(STDERR)) fclose(STDERR);
?>

If you background the process using pcntl_fork() AND close these, exec can start the process without redirected input.  The same issue was causing the CentOS GUI to hang if I attempted to start my service from there until I added the above.

This of course assumes you're already doing something else with all the output.  I'm logging all my output using Pear Log and am using set_error_handler() to handle all catchable php errors using the the logger as well.

ernestokarim at gmail dot com (2010-09-07 21:07:21)

For these persons who has problems running programs with graphical interfaces(windows) in Windows/Apache/PHP here is the solution:
Start > Run > "services.msc"
Search the Apache Service, right click and select Properties.
You will see two radio buttons, check the first if it isn't, and then check too the checkbox below.
Now restart Apache and oyu will see any kind of windows when executing a program.
Enjoy!

elwiz at 3e dot pl (2010-09-06 06:10:11)

On Windows-Apache-PHP servers there is a problem with using the exec command more than once at the same time. If a script (with the exec command) is loaded more than once by the same user at the same time the server will freeze.
In my case the PHP script using the exec command was used as the source of an image tag. More than one image in one HTML made the server stop.
The problem is described here (http://bugs.php.net/bug.php?id=44942) toghether with a solution - stop the session before the exec command and start it again after it.

<?php

session_write_close
();
exec($cmd);
session_start();

?>

arharp at gmail dot com (2010-04-07 07:19:54)

A simple function to see if exec() is enabled on the server:

<?php
function exec_enabled() {
  
$disabled explode(', 'ini_get('disable_functions'));
  return !
in_array('exec'$disabled);
}
?>

florin from syneto net (2009-11-25 07:06:43)

A simple way to initialize $output before calling exec() on the same line:
<?php
    exec
($command$output = array());
?>

lwalker at snet dot net (2009-09-10 07:09:28)

For server 2003 IIs 6 php 5.2.10 this works

<?php
$tmp 
exec("c:\\Image\\gm.exe convert c:\\Image\\file1.tiff c:\\Image\\file1.jpg"$results); 
?>

You must assign rights to the folder or exe. hopes this helps someone.

greg dot fenton at gmail dot com (2009-05-21 09:27:46)

It is possible to configure IIS so that user authentication is against an NT domain. Giving read & execute permissions to the IUSR_* user only helps for anonymous access.
For non-anonymous, give "Domain Users" read & execute permissions:
c:> cacls %COMSPEC% /E /G "%USERDOMAIN%\Domain Users":R
or more specifically:
c:> cacls c:\windows\system32\cmd.exe /E /G MYDOMAIN\Domain Users:R
For security reasons, it is strongly advised to NOT provide the IUSR_* access to cmd.exe at all.

bahri at bahri dot info (2009-03-20 01:15:06)

[NOTE BY danbrown AT php DOT net: The following is a Linux script that the contributor of this note suggests be placed in a file named 'pstools.inc.php' to execute a process, check if a process exists, and kill a process by ID.  Inspired by the Windows version at http://php.net/exec#59428 ]


<?php
  
function PsExecute($command$timeout 60$sleep 2) {
        
// First, execute the process, get the process ID

        
$pid PsExec($command);

        if( 
$pid === false )
            return 
false;

        
$cur 0;
        
// Second, loop for $timeout seconds checking if process is running
        
while( $cur $timeout ) {
            
sleep($sleep);
            
$cur += $sleep;
            
// If process is no longer running, return true;

           
echo "\n ---- $cur ------ \n";

            if( !
PsExists($pid) )
                return 
true// Process must have exited, success!
        
}

        
// If process is still running after timeout, kill the process and return false
        
PsKill($pid);
        return 
false;
    }

    function 
PsExec($commandJob) {

        
$command $commandJob.' > /dev/null 2>&1 & echo $!';
        
exec($command ,$op);
        
$pid = (int)$op[0];

        if(
$pid!="") return $pid;

        return 
false;
    }

    function 
PsExists($pid) {

        
exec("ps ax | grep $pid 2>&1"$output);

        while( list(,
$row) = each($output) ) {

                
$row_array explode(" "$row);
                
$check_pid $row_array[0];

                if(
$pid == $check_pid) {
                        return 
true;
                }

        }

        return 
false;
    }

    function 
PsKill($pid) {
        
exec("kill -9 $pid"$output);
    }
?>

skuberski at hotmail dot com (2009-02-28 08:40:28)

If you're on windows, advice to use Sysinternals (procmon.exe from live.sysinternals.com) is pretty darn good. Saved me also a lot of time, and keeped me from having to open up my entire server to the anonymous web user.

dell_petter at hotmail dot com (2009-02-04 02:52:04)

(This is for linux users only).

We know now how we can fork a process in linux with the & operator.
And by using command: nohup MY_COMMAND > /dev/null 2>&1 & echo $! we can return the pid of the process.

This small class is made so you can keep in track of your created processes ( meaning start/stop/status ).

You may use it to start a process or join an exisiting PID process.

<?php
    
// You may use status(), start(), and stop(). notice that start() method gets called automatically one time.
    
$process = new Process('ls -al');

    
// or if you got the pid, however here only the status() metod will work.
    
$process = new Process();
    
$process.setPid(my_pid);
?>

<?php
    
// Then you can start/stop/ check status of the job.
    
$process.stop();
    
$process.start();
    if (
$process.status()){
        echo 
"The process is currently running";
    }else{
        echo 
"The process is not running.";
    }
?>

<?php
/* An easy way to keep in track of external processes.
 * Ever wanted to execute a process in php, but you still wanted to have somewhat controll of the process ? Well.. This is a way of doing it.
 * @compability: Linux only. (Windows does not work).
 * @author: Peec
 */
class Process{
    private 
$pid;
    private 
$command;

    public function 
__construct($cl=false){
        if (
$cl != false){
            
$this->command $cl;
            
$this->runCom();
        }
    }
    private function 
runCom(){
        
$command 'nohup '.$this->command.' > /dev/null 2>&1 & echo $!';
        
exec($command ,$op);
        
$this->pid = (int)$op[0];
    }

    public function 
setPid($pid){
        
$this->pid $pid;
    }

    public function 
getPid(){
        return 
$this->pid;
    }

    public function 
status(){
        
$command 'ps -p '.$this->pid;
        
exec($command,$op);
        if (!isset(
$op[1]))return false;
        else return 
true;
    }

    public function 
start(){
        if (
$this->command != '')$this->runCom();
        else return 
true;
    }

    public function 
stop(){
        
$command 'kill '.$this->pid;
        
exec($command);
        if (
$this->status() == false)return true;
        else return 
false;
    }
}
?>

henze (2008-11-12 08:57:04)

if you are using exec on a w2k3 machine with IIS and after a few times the page or IIS just hangs, you should add: " && exit" to your command.
this way the cmd will always exit.

example:
<?php
    $computername 
"MyComputer";
    
$ip gethostbyname($computername);
    
exec("ping ".$ip." -n 1 -w 90 && exit"$output);
    
print_r($output);
?>

You could also try this when you have problems with the system-function or any other method you use to execute a program!

Maybe also useful when using apache, but I'm not sure about that!

ben (2008-10-19 06:04:19)

If you're having problems with any of the exec(), system() etc. functions not working properly on windows, finding the cause can be very frustrating, as is hard to diagnose.
I've found the free Process Monitor from Sysinternals (procmon.exe from live.sysinternals.com) to be VERY helpful here. You can monitor anything done by e.g. php.exe, cmd.exe and yourprogram.exe and it will list every access to files, registry etc. with return codes. You usually find some ACCESS DENIED somehwer in the log, correct the file's permissions and it works.
Has saved me a LOT of time.

sbourazanis at hotmail dot com (2008-10-18 14:49:07)

Problem:
PHP's System program execution functions do not seem to execute Win32 GUI applications.

Solution:
1.Give %system32%\cmd.exe read/execute permissions to IUSR account.
Why ?:
Delimits the unable to fork errors.

2.Make your web server's executable to interact with desktop and restart it.
Why ?:
If not you cannot see the GUI

3a.Use SysInternals Psexec with -i -d switches:
<?php
exec
("Psexec.exe -i -d  yourexe.exe");
?>
or
3b.Use Windows scripting shell COM object with false parameter to its Run Function:
<?php
function _exec($cmd

   
$WshShell = new COM("WScript.Shell"); 
   
$oExec $WshShell->Run($cmd0,false); 
   echo 
$cmd;
   return 
$oExec == true false
}
_exec("youexe.exe");
?>
Why ?:
If you use just exec then PHP waits for exe to terminate, but psexec with -d option or WshShell->Run with false option overpass this limitation and do not wait for process termination.

I hope this will help all from months' headaches...

Arno van den Brink (2008-10-13 08:04:41)

This will execute $cmd in the background (no cmd window) without PHP waiting for it to finish, on both Windows and Unix.

<?php
function execInBackground($cmd) {
    if (
substr(php_uname(), 07) == "Windows"){
        
pclose(popen("start /B "$cmd"r"));  
    }
    else {
        
exec($cmd " > /dev/null &");   
    }
}
?>

molokoloco at gmail dot com (2008-10-08 01:08:10)

On window.... escape char is "^"
>> this is working :
exec("\"C:\\Program Files\\VideoLAN\\VLC\\vlc\" get_video?video_id=aSW7YTk7tFs^&t=hash^&fmt=18 --sout=#transcode{ vcodec=h264,vb=768,scale=1,acodec=mpga,ab=96,channels=2 }:duplicate{ dst=std{access=udp,mux=ts,dst=239.192.1.1:1235} } ");
The parameters in the URL (&t=) not breaking the command now.....

philippe dot hajjar at montgomerycollege dot edu (2008-09-24 20:21:44)

I was having trouble using the PHP exec command to execute any batch file. Executing other commands (i.e., "dir") works fine). But if I executed a batch file, I receieved no output from the exec command.
The server setup I have consists of Windows Server 2003 server running IIS6 and PHP 5.2.3. On this server, I have:
1. Granted execute permissions to the Internet User on c:\windows\system32\cmd.exe.
2. Granted Everyone->Full Control to the directory in which the batch file is written.
3. Granted Everyone->Full Control on the entire c:\cygwin\bin directory and its contents.
4. Granted the Internet User "log on as batch" permissions.
5. Specified the full path to each file being executed.
6. Tested these scripts running from the command line on the server and they work just fine.
7. Ensured that %systemroot%\system32 is in the system path.
It turns out that even with all of the above in place on the server, I had to specify the full path to cmd.exe in the exec call.
When I used the call:
$output = exec("c:\\windows\\system32\\cmd.exe /c $batchFileToRun");
then everything worked fine. In my situation, $batchFileToRun was the actual system path to the batch file (i.e., the result of a call to realpath()).

frantik (2008-09-17 23:53:18)

<?php

function _exec($cmd)

   
$WshShell = new COM("WScript.Shell");
   
$cwd getcwd();
   if (
strpos($cwd,' '))
   {  if (
$pos strpos($cmd' '))
      {  
$cmd substr($cmd0$pos) . '" ' substr($cmd$pos);
      }
      else
      {  
$cmd .= '"';
      }
      
$cwd '"' $cwd;
   }   
   
$oExec $WshShell->Run("cmd /C \" $cwd\\$cmd\""0,true);
   
   return 
$oExec == true false;
}
?>

capture output using ob_start() if you like. Extra code looks for spaces and adds quote marks as they are needed

sandaimespaceman at gmail dot com (2008-09-01 00:13:49)

You can't just let it execute a macro/bot such as AutoIt and let it start video encoder, because the www-data user doesn't have a display manager
I tried to use exec('firefox') but Firefox doesn't show up.

aurora-glacialis at gmx dot de (2008-08-21 02:48:05)

The article on exec() tells you to use passthrough() if you want to get more than the last line of output from a command. However mor appropriate would be to refer to shell_exec(), since passthrough will output the result (just like print()) whereas shell_exec() will give the whole output as a $string, which is more likely the thing you want if you are not content with exec() delivering only the last line as $string

stephen dot hughes at gmail dot com (2008-08-18 08:03:04)

For windows, winnt.. IIS6 and php 5 using the dll.
I was trying to figure out why exec commands were not working. There is a post here suggesting you add iusr to the whole C drive which I am not ok with.
I eventually found that if I allowed the iusr account to access C:\windows\system32\cmd.exe things worked.
Hope this helps.
~Stephen

engtejeda at hotmail dot com (2008-06-14 23:09:37)

Task: Invoke psexec from php to execute a command on a remote computer.
Environment:
-Windows XP Professional, Service Pack 3
-Apache 2.2 Installed (I used the version bundled in XAMP 1.6.6a)
-The executable to be run must be in your system PATH!!
PHP Script:
<?php
exec 
("psexec -u someusername -p somepassword -c \\\\someipaddressORHostname someprogram.exe");
#sample command
#exec ("psexec -u JoeShmoe -p ShrimpLover529 -c \\\\192.168.22.156 cleanfiles.exe");
?>
Problems:
-I kept getting Access Denied Errors
Observation(s):
-I noticed that when I put that same psexec command in a batch file and started that batch file with the system account, I would get the same error
-This lead me to the cause
Cause:
-Apache was running as the system account, and so any process invoked by php was started as the system account
-Starting a batch file that accesses a remote computer using the local system account is a NO NO (at least for my setup)
Solution:
-Configure the Apache service to start as an account other than system (It must have appropriate permissions on the local computer)
Start-->Run-->Services.msc-->RightClick Apache Service-->Properties-->Logon Tab-->Enter in value for "Log on As"

Now load the same php page again.
Look at the error.log again
You should see an error code 0 returned for the process executed, indicating a successful run

dweston at hotmail dot co dot uk (2008-05-13 13:29:06)

I was thinking on how to make a wee command that can be used for getting the Memory AND CPU usage of a program. 

<?php

function GetProgCpuUsage($program)
{
    if(!
$program) return -1;
    
    
$c_pid exec("ps aux | grep ".$program." | grep -v grep | grep -v su | awk {'print $3'}");
    return 
$c_pid;
}

function 
GetProgMemUsage($program)
{
    if(!
$program) return -1;
    
    
$c_pid exec("ps aux | grep ".$program." | grep -v grep | grep -v su | awk {'print $4'}");
    return 
$c_pid;
}

?>

What this does is get the program's information, and splits it into either the CPU or MEM usage.

Examples:

<?php

    
echo "CPU use of Program: ".GetProgCpuUsage($randomprogram)."%";
    echo 
"Memuse of Program: ".GetProgMemUsage($randomprogram)."%";

?>

Nice and simple. :)

harmor (2008-05-07 09:18:54)

If you attempt to call a script that is not executable (i.e. not chmod +x or chmod 755), then you'll get a return error of 126.

<?php

$output 
= array();
$return_var 0;
exec('foo.sh'$output$return_var);

echo 
$return_var;   /* 126 */

?>

stefanfj at gmx dot de (2008-03-03 07:29:25)

If you try to use the psexec from Sysinternals on your Windows Server for background-processes that need special user-rights and get an "Access denied" oder "Wrong user or password" notice, although your username and password is right, this could help you getting around this bug.

<?php
$command 
"c:\directory1\psexec.exe \\127.0.0.1 -u username -p password c:\directory2\commandtoexecute.exe";
exec($command);
?>

jim dot filter at gmail dot com (2008-03-03 06:45:20)

You can embed php into a batch file so that it is essentially "double-click" to run.  This might be useful for script that does search and replace in numerous files or other tedious task that are too complex for batch files but don't warrant greater attention.  Its really quite simple I'm sure someone has thought of it before. You can add whatever batch code you want after :START just make sure you exit before you get to */ so Windows doesn't fuss. @php %0  basically is saying "Open this file with php and run its php code". Obviously its really only a useful trick on Windows, I only really use it for update scripts on our company's servers. I suppose you could also just set Windows to open php files with php.exe but that seems like a rather stupid thing to do as you would most often want to edit php files, not run them directly. @pause is optional of course, but you may want to look at what php outputted to the command line before it exits.

example.bat:

@GOTO START
<?php

  
...php code...

  
/*
  :START
  ...batch code...
  @php %0
  @pause
  @exit
  */ 
?>

dr_jones153 at hotmail dot com (2008-01-23 07:04:48)

If SAFE_MODE is on, and you are trying to run a script in the background by appending "> /dev/null 2> /dev/null & echo $!" to the command line, the browser will hang until the script is done.
My solution:
Create a shell script (ex. runscript.sh) which contains the execution line for the script you are trying to run in the background.
The runscript.sh is run by an exec() call without the redirect string, which is now placed in the runscript.sh.
runscript.sh will return almost immediately because output of the original script is redirected, and so will not hang your browser and the script runs fine in the background.

bzz at mail dot com (2008-01-11 12:02:05)

//if you just exec wshost.exe with the .vbs file as an argument, it will run fine.

<?php
//Execute a .vbs file
$f "test.vbs";
execu("whost $f");
?>

feedback at nospam fraktus dot com (2007-07-31 23:53:08)

When I tried to exec in my dreamhost virtual host nothing worked until I moved my binary outside of the web directory and then it worked without any problem. You may have the same problem.

bachya1208 at gmail dot com (2007-07-31 12:24:23)

Does anyone know of any restrictions on using exec() in a virtual host? I have complete control of my apache server, but obviously prefer to section content into virtual hosts.
exec() doesn't do anything when applied to code inside a virtual host for me...

Farhad Malekpour (2007-07-26 04:24:59)

If you're trying to use exec in a script that uses signal SIGCHLD, (i.e. pcntl_signal(SIGCHLD,'sigHandler');) it will return -1 as the exit code of the command (although output is correct!). To resolve this remove the signal handler and add it again after exec. Code will be something like this:
...
pcntl_signal(SIGCHLD, 'sigHandler');
...
...
(more codes, functions, classes, etc)
...
...
// Now executing the command via exec
// Clear the signal
pcntl_signal(SIGCHLD, SIG_DFL);
// Execute the command
exec('mycommand',$output,$retval);
// Set the signal back to our handler
pcntl_signal(SIGCHLD, 'sigHandler');
// At this point we have correct value of $retval.
Same solution can apply to system and passthru as well.

WindowsPHPUser (2007-07-10 23:42:39)

I had trouble getting the program execution functions to work on a Windows server, even though it worked on my test machine. Here is something that helped:
First, set the security permissions on the exe to allow USR_MachineName to execute the program.
Then I changed the 'Log on as Batch Job' local security policy to include the IUSR account (and rebooted). After I made that change, the programs were allowed to run.
I also limited the permissions for the IUSR account to read and execute only.

conrad (2007-06-07 10:02:42)

Windows note: Despite people syaing that you CAN you CANNOT exec a .vbs windows script host (wsh) file using exec() - you need to execute your vbs file via a "windows link" (.lnk file - a bog standard shortcut)
ie: I right click and dragged my datapurge.vbs a few pixels to the side and chose "Create Shortcuts Here" and then deleted the autogenerated "Short cut to datapurge.vbs" and renamed it merely datapurge.vbs - bear in mind as far as php is concerend it's ACTUALLY called datapurge.vbs.lnk
however you will need to sleep(); your php page to make sure the .vbs has had time to run if you intend on using the vbs output (say a file your vbs made) this is becase the .lnk instantly runs and php immediately continues processing without barely skipping a beat even if the vbs takes yonks to run.
If you are wondering why anyone would ever WANT to run a .vbs from within .php I can see some reasons - there are various windows platform objects just not accesible from php. (and most php programmers know a little .asp though they would say they don't! so asp-a-like .vbs is the logical choice)

skchandon at skchandon dot com (2007-04-25 07:46:49)

PHP Exec : Delete statement execution problem
If filename is blank for exec: delete statement then it hangs the php execution, hence have to trap it as follows
 
<?php
$fname
=$_POST["fname"];
 if (
$fname!="")                    //  TRAP
 
{  exec ("del c:\\temp\\$fname"); }
 
?>

Zack / Nog (2007-04-22 10:23:29)

Hey guys, I just wanted to drop a note after spending , i dunno 6 hours or so on getting exec() to work on an outside program with Win2k3 on IIS6 and PHP installed as an ISAPI module. I originally had it installed with Ensim, but it got confusing, so after a while of it not working I installed the latest PHP 5 binaries.
First thing I did was download the latest PHP 5 Binaries for Windows, but NOT THE INSTALLER. I dunno what the installer does, but I read previously not to use it, so I set it up like that.
After that I went into IIS manager, clicked on Add Extensions, added .PHP and changed the executing location to c:\php\php5isapi.dll. Then I went into the website portion, right clicked on it, went to properties, clicked on the Home site tab, clicked Configure and added an extension with extention = .php and executable = c:\php\php5isapi.dll.
After this , the thing that FINALLY WORKED! was , well, see at first I setup permissions by adding IUSR_MyCompName to the allowed list, and checked Full control, so i thought it had permissions.... Well, it was being overwritten which is what bit me...
I went into the C: drive, and right clicked and went to Properties, clicked on the Security tab, and then clicked on Advanced in the bottom right. If you see any IUSR with Deny, simply remove it.
Then right click on c:\php and do the same, after all Deny's have been deleted (Which override allows, which was my issue), go into c:\php and open the security tab, make sure IUSR_yourcompname is added as allow, and then do the same for c:\yoursoftwarefolder\ so your software has the same permissions.
The deny thing on C: overriding my c:\folder with allow was blowing it all up for me, I deleted the deny and made sure IUSR_mycompname was with full control on my outside apps file, and VUALA !!!
Theres now some trouble with it asking for a confirmation, but i'll figure that out later, i can at least run it without troubles :)
ALSO! DO NOT FORGET! Add C:\php and C:\outsidesoftwarefolder as Environment Variables to the Path variable in your system. It's easy, just right click my comp, properties, click advanced tab, enviornment variable button at the bottom, in the second scrolling list find the one with name of lowercase path, double click it, and on the end, add a semi-colon to end the last folder and type your folder location
so if it was originally c:\test;c:\windows\system32 and you wanna add php, make it read c:\test;c:\windows\system32;c:\php
Hope this helps someone , the thing that helped the most was the Advanced button in the security tab and removing the denies, which take ownership OVER the allows.
... My 2 cents :)

sirnuke at gmail dot com (2006-09-26 22:26:48)

Note that on Linux/UNIX/etc, both the command and any parameters you send is visible to anyone with access to ps.

For example, take some php code that calls an external program, and sends a sort of password as a parameter.

<?php
exec
("/usr/bin/secureprogram password");
?>

The entire string (actually probably something like "secureprogram password") will be visible to any user that executes ps -A -F.  If you are going to be doing a lot of external calling, or any of it needs to be somewhat secure, you are probably better off writing a php extension.

sinisa dot dukaric at gmail dot com (2006-08-16 07:10:37)

Recently I had to do some "root" stuff via PHP - I could do it through cronjob based on the database, but since I was too lazy with doing that, I just wrote a shell script to create all the IMAP stuff, chown properly all the Maildirs and provision the user on the local system.
Executing that command as another user from inside of PHP was like this...
<code>
@exec("echo 'apache' | /usr/bin/sudo -u mail -S /var/www/html/mailset.sh $name");
</code>
"Advantage" is that you can run in this way commands as any sudoer on your system which can be fine-tuned and pretty useful. But again - password is echoed in cleartext and option "-S" tells sudo to take password from stdin which he does of course.
Major security risk - do it only if you really need to run some commands as different users (nologin users) and if you are really lazy :)
Now, my solution is a cronjob which runs every 5 mins and gets datasets from the MySQL table and does the work without exploiting any exec() from within PHP - which is the right way to do it.

Jelsamino (2006-05-11 05:41:39)

If you need generate new data .htpasswd file:

<?php
$command
="htpasswd -nb ".$login."".$password;
exec($command,$res);
echo 
$res[0];
?>

Luck!!!!!!!

(2006-03-29 04:12:17)

I've done a C program to act as a "timeout controller" process, by forking itself and executing some other command received as parameter.

Then, in PHP I have a function that calls commands this way:

<?php
...
$command "tout_controller <tout> <command_name> <command_args>"
exec($command,$status);
echo 
"Exit status code of command is $status";
...
?>

I've noticed that exit status code returned from a C process is a "special" integer.

I wanted "command" exit status code to be returned to controller, and then controller to exit with same status code (to get this status from PHP).
Exit status was always 0 !!!

To solve this, i've found a C macro to use inside tout_controller:

<C code snippet>
..
waitpid(pid,&status,0); // wait for process that execs COMMAND
..
//exit(status); // that doesn't work
exit(WEXITSTATUS(ret)); // that's ok
..
</C code snippet>

It isn't exactly a PHP note, but may be useful to help some desperated programmer's ;)

amandato (at) gmail (period) com (2005-12-06 12:51:03)

Running a command that may never time out on a windows server inspired the following code.  The PsExecute() function allows you to run a command and make it time out after a set period of time.  The sleep parameter is the number of seconds the script will pause becore checking if the process is complete.

Code utilizes the PsTools, found here: http://www.sysinternals.com/ntw2k/freeware/pstools.shtml

Copy and paste the following code into an include file:
<?php
// pstools.inc.php

    
function PsExecute($command$timeout 60$sleep 2) {
        
// First, execute the process, get the process ID
        
$pid PsExec($command);
        
        if( 
$pid === false )
            return 
false;
        
        
$cur 0;
        
// Second, loop for $timeout seconds checking if process is running
        
while( $cur $timeout ) {
            
sleep($sleep);
            
$cur += $sleep;
            
// If process is no longer running, return true;
            
if( !PsExists($pid) )
                return 
true// Process must have exited, success!
        
}
        
        
// If process is still running after timeout, kill the process and return false
        
PsKill($pid);
        return 
false;
    }
    
    function 
PsExec($command) {
        
execdirname(__FILE__). "\\psexec.exe -s -d $command  2>&1"$output);

        while( list(,
$row) = each($output) ) {
            
$found stripos($row'with process ID ');
            if( 
$found )
                return 
substr($row$foundstrlen($row)-$found-strlen('with process ID ')-1); // chop off last character '.' from line
        
}
        
        return 
false;
    }
    
    function 
PsExists($pid) {
        
execdirname(__FILE__). "\\pslist.exe $pid 2>&1"$output);

        while( list(,
$row) = each($output) ) {
            
$found stristr($row"process $pid was not found");
            if( 
$found !== false )
                return 
false;
        }
        
        return 
true;
    }
    
    function 
PsKill($pid) {
        
execdirname(__FILE__). "\\pskill.exe $pid"$output);
    }
?>

Place the above include file and the PsTools from (http://www.sysinternals.com/ntw2k/freeware/pstools.shtml) in the same directory.

simoncpu (2005-11-29 23:48:20)

Sometimes, it is convenient to let exec() return the status of the executed command, rather than return the last line from the result of that command. In Unix, just do:
$ret = exec('foo; echo $?');
Remember not to overdo it though. ;)
[ simon.cpu ]

Bob-PHP at HamsterRepublic dot com (2005-10-18 11:00:33)

exec strips trailing whitespace off the output of a command. This makes it impossible to capture signifigant whitespace. For example, suppose that a program outputs columns of tab-delimited text, and the last column contains empty fields on some lines. The trailing tabs are important, but get thrown away.
If you need to preserve trialing whitespace, you must use popen() instead.

clive at pluton dot co dot uk (2005-10-15 03:35:05)

When trying to run an external command-line application in Windows 2000 (Using IIS), I found that it was behaving differently from when I manually ran it from a DOS prompt.
Turned out to be an issue with the process protection. Actually, it wasn't the application itself that was having the problem but one it ran below it! To fix it, open computer management, right-click on Default Web Site, select the Home Directory tab and change Application Protection to 'Low (IIS Process)'.
Note, this is a rather dangerous thing to do, but in cases where it's the only option...

rivera at spamjoy dot unr dot edu (2005-10-06 13:17:00)

windExec() reloaded:
* unique timestamp name was probably a good idea for multiple instances of function running @ same time
* includes handy FG/BG parameter

<?php
define 
('EXEC_TMP_DIR''C:\tmp');

function 
windExec($cmd,$mode=''){
    
// runs a command line and returns
    // the output even for Wind XP SP2
    // example: $cmd = "fullpath.exe -arg1 -arg2"
    // $outputString = windExec($cmd, "FG");
    // OR windExec($cmd);
    // (no output since it runs in BG by default)
    // for output requires that EXEC_TMP_DIR be defined

    // Setup the command to run from "run"
    
$cmdline "cmd /C $cmd";

    
// set-up the output and mode
    
if ($mode=='FG'){
        
$outputfile EXEC_TMP_DIR "\\" time() . ".txt";
        
$cmdline .= " > $outputfile";
        
$m true;
    }
    else 
$m false;

    
// Make a new instance of the COM object
    
$WshShell = new COM("WScript.Shell");

    
// Make the command window but dont show it.
    
$oExec $WshShell->Run($cmdline0$m);

    if (
$outputfile){
        
// Read the tmp file.
        
$retStr file_get_contents($outputfile);
        
// Delete the temp_file.
        
unlink($outputfile);
    }
    else 
$retStr "";

    return 
$retStr;
}

ewilde (2005-09-20 16:55:46)

To my way of thinking, it is a good idea to execute programs from the cgi-bin directory of the Web server, to get a little control over configuring a system (at install time, a pointer to the actual program can be symlinked from the cgi-bin directory and the code won't ever have to be changed).  If you'd like to do this, under Apache at least, the following should work:

<?php
  
if (!($ProgInfo apache_lookup_uri(/cgi-bin/myprog)))
    
$ProgPath = /usr/bin/myprog;
  else
    {
    if (
is_object($ProgInfo)) $ProgPath $ProgInfo->filename;
    else 
$ProgPath $ProgInfo["filename"];
    }

exec("$ProgPath ...");
?>

mbirth at webwriters.de (2005-09-13 23:42:29)

I had to combine many PDFs into a single one using pdftk and did this by writing the commands into a batch file and running it with exec('cmd /c blabla.cmd').
Using batch files under Windows, there's a line-length-limit of 1024 characters. So I made sure each line in the batch file doesn't exceed 1024 characters.
I now switched over to using exec('start /b ...') directly with the desired command (instead of writing it into a batch file and calling that) and played around with the line-length. Seems like the exec() command works with command-strings of up to 4096 characters in length. If the string is longer, it won't be executed.

CJ [AT] TBG (2005-09-08 10:41:18)

[EXEC] on [Windows]
Finally a simple way to get exec working w/o launching a black box window.
just do: exec('start /B "window_name" "path to your exe"',$output,$return);
The important part is the /B which makes it run in the background.

p dot koeman at wittenborg-university dot com (2005-08-29 06:22:07)

Using sudo (http://www.sudo.ws/) to exec system commands from PHP

This is a secure way to use sudo from PHP to perform sysadmin tasks from a php webapplication. (can be used with exec or passthru)

- Make a PHP script in the WWW root directory : client.php

[/home/mywebdir/html/client.php]
<?php
passthru
('echo hello world | sudo /usr/bin/php -f /home/server.php');
?>

- Make a PHP script outside the WWW directory : server.php

[/home/server.php]
<?php
echo join('',file('php://stdin'));
?>

Add a line to /etc/sudoers 

[in /etc/sudoers]
www    ALL=(ALL) NOPASSWD: /usr/bin/php -f /home/server.php

Now execute client.php in the webbrowser (as www user)
- client.php will execute sudo
- sudo will execute server.php by php as root !

In server.php you can do everything you like requiring root privileges. BEWARE ! every php script can now execute server.php, make it secure ! (filter parameters etc.)

I have tested this method and it works !
Kind regards, Pim Koeman
Wittenborg-University, Deventer, the Netherlands
http://www.wittenborg-university.com

vdweij at hotmail dot com (2005-08-09 04:18:31)

It is possible to only capture the error stream (STERR). Here it goes...
(some_command par1 par2 > /dev/null) 3>&1 1>&2 2>&3
-First STDOUT is redirected to /dev/null.
-By using parenthesis it is possible to gain control over STERR and STOUT again.
-Then switch STERR with STOUT.
The switch is using the standard variable switch method -- 3 variables (buckets) are required to swap 2 variables with each other. (you have 2 variables and you need to switch the contents - you must bring in a 3rd temporary variable to hold the contents of one value so you can properly swap them).
This link gave me this information:
http://www.cpqlinux.com/redirect.html

netshadow at madpoets dot org (2005-04-05 07:13:38)

For Win2k/XP systems, and probably NT as well, after beating my head against a wall for a few days on this, I finally found a foolproof way of backgrounding processes and continuing the script.
For some strange reason I just could not seem to get backgrounding to work with either system or exec, or with the wsh.run method for that matter. I have used all three in the past with success, but it just wasn't happening this time.
What I finally wound up doing was using psexec from the pstools package found at http://www.sysinternals.com/ntw2k/freeware/pstools.shtml
You would use it like:
exec("psexec -d blah.bat");
which will start and immediately background blah.bat and immediately resume running the rest of the php script.

bitminer at example dot com (2005-03-19 10:24:08)

I am posting this as I see quite a few people looking to create a web based interface to their MP3 player (XMMS or really what ever you want to call from the command line) on Linux.  Alas, I am not the only one, and  I did not think of it first ( suppose I have to result to other get rich quick schemes).  And even if there were a direct downloadable utility (as there is XMMS-Control) you, like me, probably want the bowl of porage that is just right.  Which means you want to make your own because current versions of X, Y, or Z just don't do what you want. 

Most of the hard work is at the linux command shell (ugh! - I heard that!  Drop and give me 20 command line scripts!)

login as root

ensure /dev/dsp has the proper access privileges
chmod a+rw /dev/dsp

add apache to the local list of users for the xserver.
xhost +local:apache@

You should see the following if apache is not added to the xserver.

Xlib: connection to ":0.0" refused by server
Xlib: No protocol specified

** CRITICAL **: Unable to open display

And I am sure that error is as clear to you as it was to me!

NOTE !!! only change the following for testing purposes so that you can su to apache from root and test xmms !!!!

Temporarily change the line 

apache:x:48:48:Apache:/var/www:/sbin/nologin

To
apache:x:48:48:Apache:/var/www:/bin/bash

so that you can test out apache access to the Xserver and XMMS.

su apache
xmms
!!! Play a file - Don't just read this actually play a file!!!  The reason is that if it fails xmms will likely give an error you can track down like a greyhound chases that little bunny at the dog track! (speaking of get rich quick schemes)

And for the grand finale! 

If you can call xmms from the command line you can likely do the following (unless you are running php in safe mode).  Ensure that the wav, mp3, or whatever you decide to test it with is accessible to apache.  I put the file into /var/www/html/icould.wav and chmod a+rw icould.wav

<?php
echo ' Executing XMMS ';
// note you could use system too!
//echo system( '/usr/bin/xmms --play icould.wav', $retval );
exec ('/usr/bin/xmms --play icould.wav');
?>

At your browser ensure you hit shift+refresh(button) so your browser doesn't give you a cahed the web page.

Brian J. Davis

david houlder (2005-02-22 03:47:17)

The note regarding how exec() works under safe_mode is wrong.
echo y | echo x does not become echo "y | echo x". It essentially becomes echo "y" "|" "echo" "x". The entire string is passed through escapeshellcmd(), which effectively splits arguments at spaces. Note that this makes it impossible to reliably pass arguments containing spaces to exec() in safe_mode. Since 4.3.3 escapeshellcmd() tries to pass quoted arguments through (so you could try exec("cmd 'arg 1' 'arg 2'")), but not on win32, and will still wrongly backslash escape any punctuation characters inside the quotes.
Not only can the path not contain '..' components, but no directory or filename can contain the string '..'. e.g. /path/to/my..executable will refuse to run.

layton at layton dot tk (2005-01-18 15:52:58)

This is the second time this one got me, I thought someone else might find this note useful too.
I am creating a long running exec'd process that I can access with page submissions up to 2 hours later. The problem is this, the first time I access the page everything works like it should. The second time the web browser waits and waits and never gets any messages -- the CPU time is not affected so it is apparent that something is blocked.
What is actually happening is that all of the open files are being copied to the exec'd process -- including the network connections. So the second time I try to access the web page, I am being given the old http network connection which is now being ignored.
The solution is to scan all file handles from 3 on up and close them all. Remember that handles 0, 1, and 2 are standard input, standard output, and standard error.

(2005-01-13 04:38:32)

I wanted my script to:

* execute an external command.
* check if the execution was ok. (i.e. the return level)
* log the error output if the execution wasn't ok.
* not print the command's output in my script's output.

I saw the exec, system, shell_exec and passthru functions, and deduced that the solution was to redirect the standard error (stderr) to the standard output (stdout). It's not very clean, since it mixes stderr with stdout, and I only wanted to log the stderr. But it seems to be the only solution (suggestions are welcome).

This is the code I use:

<?php

$com
"ls";     # command

exec("$com 2>&1"$out$err);                                           
if (
$errmy_log_func(join("\n"$out));

?>

chads2k2.yahoo.com (2004-12-13 10:38:05)

This will execute a exectuable from the 
command window without the command
window even being seen.

Much help was given by Michael Sheakoski
as he stated below this in one of his other
scripts.  The problem I had was that I want
to have arguments be sent to the .exe.

This will run the exe and then whatever it
returned will be dealt with.

Tested with:
Windows XP Pro SP1
Apache2
PHP 4.3.x
IIS6 as well

Here is the snippet.
<?php
// Get a good ol' timestamp.  Unique and it works.
$unixtime time();

// Sets up your exe or other path.
$cmd 'C:\\path\\to\\program\\argue2.exe';

// Setup an array of arguments to be sent.
$arg[] = '1';
$arg[] = '2';
$arg[] = '3';
$arg[] = '4';
$arg[] = '5';

// Pick a place for the temp_file to be placed.
$outputfile 'C:\\path\\to\\tmp\\unixtime.txt';

// Setup the command to run from "run"
$cmdline "cmd /C $cmd " implode(' '$arg) . " > $outputfile";

// Make a new instance of the COM object
$WshShell = new COM("WScript.Shell");  

// Make the command window but don't show it.
$oExec $WshShell->Run($cmdline0true); 

// Read the file file.
$output file($outputfile);

// Delete the temp_file.
unlink($outputfile);

// Take the output and break the array apart.  
// If you don't know what is coming out do:
// print_r("$output");
foreach($output as $temp_output)
{
   
// Check the output's return code.
   
if($temp_output == 1)
   {
      
// Tell the user it was correct.
      
echo "All is good";
   }else{
      
// Tell the user something goofed.
      
echo "Didn't go smoothly.";
   }
}
?>

(2004-10-13 09:46:54)

if you want to use rsh and nohup, you should do this:

<?php 
   
//...
   
exec("nohup  rsh -n *command* 1>/dev/null/ 2>&1 &"); 
   
//..
?>

or 

<?php 
   
//...
   
exec("nohup  rsh -n *command* 1>result.log 2>&1 &"); 
   
//...
?>

php-contrib at i-ps dot net (2004-10-12 06:30:39)

I had a bit of trouble using exec with Windows when passing a parameter to a PHP script file. I found I needed to create a Windows batch "wrapper" file to get the script file to accept the optional argument.
1) PHP script file exists:
c:\www\script.php
2) PHP is installed in:
c:\www\php\
3) BAT file contains:
@c:\www\php\cli\php.exe c:\www\script.php %1
and is saved as:
c:\www\script.bat
4) Use exec statement from PHP:
exec("c:\www\script.bat $arg", $output);
If you want to pass more than one argument, carry on with %2, %3, %4, ..., ... in your BAT file.
Hope this helps somebody

msheakoski @t yahoo d@t com (2004-07-08 08:40:21)

I too wrestled with getting a program to run in the background in Windows while the script continues to execute.  This method unlike the other solutions allows you to start any program minimized, maximized, or with no window at all.  llbra@phpbrasil's solution does work but it sometimes produces an unwanted window on the desktop when you really want the task to run hidden.

start Notepad.exe minimized in the background:

<?php
$WshShell 
= new COM("WScript.Shell");
$oExec $WshShell->Run("notepad.exe"7false);
?>

start a shell command invisible in the background:
<?php
$WshShell 
= new COM("WScript.Shell");
$oExec $WshShell->Run("cmd /C dir /S %windir%"0false);
?>

start MSPaint maximized and wait for you to close it before continuing the script:
<?php
$WshShell 
= new COM("WScript.Shell");
$oExec $WshShell->Run("mspaint.exe"3true);
?>

For more info on the Run() method go to:
http://msdn.microsoft.com/library/en-us/script56/html/wsMthRun.asp

llbra@phpbrasil (2004-07-05 17:30:30)

If you want to run somenthing but php just keep processing data and don?t answer until the program is closed (run in background mode, without interfering the program), from the note ( If you start a program using this function ... PHP will hang until the execution of the program ends ), jonas function will certainly be useful for you:

<?php
function execInBackground($path$exe$args "") {
   global 
$conf;
   
   if (
file_exists($path $exe)) {
       
chdir($path);
       if (
substr(php_uname(), 07) == "Windows"){
           
pclose(popen("start \"bla\" \"" $exe "\" " escapeshellarg($args), "r"));    
       } else {
           
exec("./" $exe " " escapeshellarg($args) . " > /dev/null &");    
       }
   }
}
?>

Thank you Jonas. It has been very useful for me.

until-june-04 at daniu dot de (2004-05-13 15:27:43)

Hi!
I just want to add a note to the function "jonas DOT info AT gmx DOT net" contributed to keep processes running in the background.
Not like with the other exec/system/passthru etc. functions if you want to execute a batch file on a MS-machine you need to add a simple exit in the last line of your batch-file otherwise the CMD task does not close and your server will be filled with dead processes ... No idea what happens with other programs .

nehle at dragonball-se dot com (2003-10-21 14:59:34)

Remember that some shell commands in *NIX needs you to set a TERM enviroment. For example:
<?php
exec
('top n 1 b i'$top$error );
echo 
nl2br(implode("\n",$top));
if (
$error){
    
exec('/usr/bin/top n 1 b 2>&1'$error );
    echo 
"Error: ";
    exit(
$error[0]);
}
?> 
This will echo "Error: TERM enviroment variable not set. " To fix it, add  TERM=xterm (Or some other terminal) to the exec-statement, like this

<?php
exec
('TERM=xterm /usr/bin/top n 1 b i'$top$error );
echo 
nl2br(implode("\n",$top));
if (
$error){
    
exec('TERM=xterm /usr/bin/top n 1 b 2>&1'$error );
    echo 
"Error: ";
    exit(
$error[0]);
}
?>

colet at putnamhill dot net (2003-09-26 15:34:39)

Technique for debuging php in *nix environments:
SSH to your php directory and enter the following:
mkfifo -m 772 .debug
tail -f .debug
Now in your php scripts direct debug messages to the debug FIFO with:
exec("echo \"Some debug statement or $var\" > .debug");
When the php executes, you can watch the output in your terminal app.
This is helpful in situations where it's awkward to debug in a browser (i.e. header commands).

jonas DOT info AT gmx DOT net (2003-09-12 09:24:47)

On WinXP with Apache2 and PHP 4.3.3 you cannot start a program in background with exec and start. you have to do the following. This function should work on Windows and Unix, too. 

<?php
function execInBackground($path$exe$args "") {
    global 
$conf;
    
    if (
file_exists($path $exe)) {
        
chdir($path);
        if (
substr(php_uname(), 07) == "Windows"){
            
pclose(popen("start \"bla\" \"" $exe "\" " escapeshellarg($args), "r"));    
        } else {
            
exec("./" $exe " " escapeshellarg($args) . " > /dev/null &");    
        }
    }
}
?>

I have this tested in Win XP and SUSE Linux with Apache and PHP 4.3.3.

mauroi at digbang dot com (2003-09-03 09:18:56)

Well, after hours of fighting with output redirection, input redirection, error redirection, session_write_close (), blah blah blah, I think I found an easy way to execute a program in background. I used the following command:
Proc_Close (Proc_Open ("./command --foo=1 &", Array (), $foo));
With the second argument you tell proc_open not to open any pipe to the new process, so you don't have to worry about anything. The third argument is only needed because it's not optional. Also, with the '&' operator the program runs in background so the control is returned to PHP as soon as Proc_Close is executed (it doesn't have to wait).
In my case I don't use the user session in the executed script (there's no way it can be identified if it is not sended as a cookie or URL) so there's no need for session_write_close (correct me if I'm wrong with this).
It worked for me.

bishupaulose at yahoo dot com (2003-06-19 11:46:48)

Using ping function in PHP
---------------------------------------

You can use the extended version of this program to check the network status and later you can add HTTP.FTP.POP3 and SMTP protocols as its part.

Access the content of exec from a variable, make radio buttons for each protocol and change the value of variable according to te radio button selection.

[Use ping with count and deadline]

<META http-equiv="Refresh" content="3">
<?php
  $str
=exec("ping -c 1 -w 1 192.168.1.216",$a,$a1);
  print 
"<table>";
  if(
strlen($str)>1){
     print
"<tr><td bgcolor='#fff000'>present</td></tr>";   
  }else{
     print
"<tr><td bgcolor='#000000'>Not present</td></tr>";       
  }
 print 
"</table> ";
?>

matt at nexxmedia dot com (2003-06-11 13:38:48)

[ Editor's note: When passing multiple args in a URL like this, be sure to enclose the URL in quotes otherwise the & will be interpreted as a detachment flag and the rest of the command will be truncated. ]
The lynx browser can be used as simple way of executing a script from a remote location without waiting for it to complete:
$command = "/usr/bin/lynx -dump https://www.anotherserver.com?var=blah >/dev/null &";
exec($command);

marc at thewebguys dot com dot au (2003-02-26 07:51:20)

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

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

iceburn at dangerzone dot c o m (2002-09-09 17:20:25)

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 "<br>";
 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...)

ronperrella at NOSPAM dot hotmail dot com (2002-08-06 11:04:45)

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

<?php
$prgfile 
tempnam("/tmp""SH");
chmod($prgfile0755);
$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.)

me at jcornelius dot com (2002-05-15 10:06:16)

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

hans at internit dot NO_SPAM dot com (2002-02-02 02:25:02)

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!

ryan at imagesmith dot com (2001-07-17 03:47:41)

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

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

ary at communicationfactory dot com (2001-06-13 16:10:06)

Remember to use unix exit(0); 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>

pkshifted at slackin dot com (2001-03-07 11:24:41)

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.

bens_nospam at benjamindsmith dot com (2001-02-15 13:19:15)

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

易百教程