|
|
CXXVII. Program Execution Functions
Those functions provide means to execute commands on the
system itself, and means to secure such commands.
Эти функции всегда доступны. Для использования этих функций не требуется проведение установки,
поскольку они являются частью ядра PHP. Данное расширение не определяет никакие директивы конфигурации в php.ini.
This extension defines a process resource, returned by
proc_open().
Данное расширение не определяет никакие константы. - Содержание
- escapeshellarg -- Escape a string to be used as a shell argument
- escapeshellcmd -- Escape shell metacharacters
- exec -- Execute an external program
- passthru -- Execute an external program and display raw output
- proc_close -- Close a process opened by proc_open() and return the exit code of that process.
- proc_get_status -- Get information about a process opened by proc_open()
- proc_nice -- Change the priority of the current process
- proc_open --
Execute a command and open file pointers for input/output
- proc_terminate -- Kills a process opened by proc_open
- shell_exec -- Execute command via shell and return the complete output as a string
- system -- Execute an external program and display the output
add a note
User Contributed Notes
Program Execution Functions
Max_R
26-Sep-2007 07:21
Just a small notice, when running PHP under MS Windows
some external command-line utilities (like 'ffmpeg.exe') output all info to stderr instead of stdout. In my case it caused apache error.log overfilling with lots of unsolicited records.
It has just taken some time for me to make the utility silent:
Simply add
">NUL 2>&1"
to the very end of your command line. It makes cmd.exe to redirect stderr to stdout and then, in one's turn, redirect stdout to NULL.
Hope this tip will save some time when dealing with such utilities.
steve dot robinson at frogneck dot com
21-May-2007 07:46
If you are trying to use exec to run a cgi and output the contents via a php file, headers need to be seperated from the content and output seperately.
Also, at least in the case of the cgi I was attempting to execute, line feeds were missing, and some javascript didn't work as a result, so you may have to add line feeds back into the resulting output. Here is the code I used to output my cgi properly...
<?PHP
putenv('REQUEST_METHOD=GET');
putenv('QUERY_STRING=' . $_SERVER['QUERY_STRING']);
$inheader=true;
foreach($output as $val){
if($val=='')
$inheader=false;
if($inheader)
header($val);
else
echo($val . "\n"); }
?>
php at fendy dot org
02-May-2007 05:51
Scheduling WinXP tasks with schtasks.exe and using PHP to execute the command, may sometime fail to work.
This is because, Apache does not have the privilege to access some of the System Files when placing the scheduling. The way I'd do: is by creating a normal user account and assign Apache service to logon as that account.
Open the 'services.msc' in the 'Run' window, look for Apache in the listing, right click and get to 'Properties'. Click at the second tab 'Log On' and fill in the 'This account' fields.
Of course, Apache needs to be installed as Service during its first setup.
Hope this helps anyone.
Fendy Ahmad
pawel_do_not at spam_me_lenart dot pl
24-Apr-2007 04:51
You must remember that if you're running your own compiled C programs and you don't get any output you probably do it like this:
printf("some text");
shell_exec and similiar functions won't display it, you must do your output as follows:
fprintf(stdout, "some text");
and then shell_exec and so will correctly read stdout (spent an hour wondering why my program isn't working when connected with PHP :)
29-Jan-2007 08:16
it seams to me the best way would be to copy cmd.exe to a secure directory somewhere under your web directory, add it to the windows path and then call it from there using system commands. It seams as though that would get arround any security holes
Rafael Palacios
29-Jan-2007 06:52
Here is a way to collect all the output of a command (standard output and standard error):
$command="your command goes here";
$output=shell_exec($command." 2>&1"); //system call
print "<pre>$output</pre>\n"; //show output
Matt-kun
08-Dec-2006 10:50
Just a simple note to help people get rid of some headaches.
when using:
<?
$filepath = "the path of the file";
exec("program -command $filepath ");
fopen($filepath,rw);
?>
Make sure you use "\ " ( \ space) for the Linux\unix path and just " " space for fopen. These are both very basic things that you wouldn't normally think to cause a problem, but when you try to pass slashes to fopen it either breaks or even better works incorrectly =D. And vise versa for any programs that use "\ " for spaces in file paths/names.
I ran into this problem when using <? exec(" cp $path "); ?> and <? fopen("$path"); ?>. To fix it I used str_replace(" ","\ ",$path); and str_replace("\ ", " ",$path);
*Note this is alot of sudo code, and there are faster more effecient ways of doing the same operations, but I thought this might help those who were going crazy over filepaths =D.
PHP at jyoppDot-com
04-Oct-2006 10:38
Here's a function to launch a low-priority background process very simply, returning control to the foreground. I found that a lot of the other approaches shown here allow the script to continue running, and the page is served up to the user, but the PHP thread that launched the process cannot be re-used until the process has completed. Stdout and stderr need to be redirected to /dev/null to prevent this.
This is for BSD/*NIX servers only (tested on Fedora Core and OSX). Win32 approaches would be necessarily very different. Omit 'nice' if you don't want to run the process with lowered priority.
<?php
function fork($shellCmd) {
exec("nice $shellCmd > /dev/null 2>&1 &");
}
?>
t dot kramer at NOSPAM dot safetbus dot de
21-Sep-2006 02:21
Trying to us the following code failed badly with various results: like "unable to fork", "access denied", "empty results", depending on what settings I used, ... even though the same code worked from command line on the server itself.
$retstr = exec('nslookup -type=mx myhost.com', $retarr);
Instead of nslookup I believe this would apply to most programs from the \system32\ directory.
I had to learn that the following finally worked:
$retstr = exec('c:\php\safedir\nslookup -type=mx myhost.com', $retarr);
... but only under the listed preconditions:
1: nslookup.exe is placed (copied) in the directory \php\safedir\
2: the directory \php\safedir\ is included in the system PATH environement variable
3: the file cmd.exe is placed in \php\ as listed by other notes above
4: the directory "c:\php\safedir\" is set in the php.ini setting
safe_mode_exec_dir = "c:\php\safedir\"
.. maybe set in php-activescript.ini as well, depending on your system setup.
5: nslookup is referenced by the full path as otherwise the file from \windows\system32\ will be called. This happend to me with empty result due to missing rights!
Hope this helps somebody saving some time and headaches.
Thomas
Arjan van Bentem
12-Jul-2006 12:38
When using Red Hat Fedora, beware of Security Enhanced Linux, SELinux.
Quoted from Red Hat: "The security goal is to make sure that Apache HTTP is only reading the static Web content, and not doing anything else such as writing to the content, connecting to database sockets, reading user home directories, etc."
These limitations include, among many other things, using exec to run external applications that happen to use sockets (or maybe access some files) such as HylaFAX "faxstat" as invoked from nweb2fax recvq.php and sendq.php.
For debugging, one could try running such commands using PHP Shell (see http://mgeisler.net/php-shell/) which might fail while execution from the real command line (as Unix user apache or httpd) yields no problem whatsoever.
See /var/log/messages for any denials due to the SELinux policy. To disable it:
- System, Administration, Security Level and Firewall
- open the SELinux tab
- click the Transition tree
- check Disable SELinux protection for Apache HTTP
- execute /etc/init.d/httpd restart
See also http://fedora.redhat.com/docs/selinux-faq/ and http://php.net/results.php?q=selinux&p=wholesite
judas dot iscariote at gmail dot com
01-Jun-2006 12:19
This functions are generally considered harmful,without proper input validation procedures are as worse as eval().
If what you are trying to do is possible using other mechanism, ** do it that way, even if it takes more time **.
Do not cry or blame PHP if your server gets "owned" due to a missing escapeshell*** in your code , you have been warned.
manokan at manokan dot net
17-Apr-2006 10:09
Lets make it even clearer, about the "unable to fork" error in exec().
By default Windows XP sets all permissions for cmd.exe for the temporary internet user account (IUSER-[computername]) to DENY. That overrides everthing.
You must modify the security on cmd.exe to give the IUSER-computername account at least read & execute and remove the DENY.
not at any dot com
23-Feb-2006 12:16
at LAST! tenacity pays off, days trying every little thing!
I didn't want batch files. I'm trying to use PHP to get rid of batch files.
I didn't want to call a file to parse the parameters to call a shell to call a file. I've got "systems" right now with batches tiered three and five deep.
I just wanted to run stuff.
CALL, tested on WinXP, will be testing on more OSes right away, in PHP4 and 5, with exec, system, works with popen, and passthru.
here is my lame sample function.
// CreateZip
function createzip ($target, $archive)
{ $ziputil = "call \"c:\\Program Files\\7-zip\\7z.exe\"";
$archived = escapeshellarg($archive);
$targeted = escapeshellarg($target);
$shellcommand= $ziputil." a -tzip ".$archived." ".$targeted."\n";
// all of the below are working in Win XP Pro
passthru ($shellcommand);
exec ($shellcommand);
system ($shellcommand);
shell_exec ($shellcommand);
$proc= popen ($shellcommand, "r"); //$proc contains output
LONG PATH NAMES WITH SPACES IN THEM ON WINDOWS!
all in a big long concatenated command line with multiple quoted-filename parameters
shell scripting bliss!
mtupker at yahoo dot com
24-Jan-2006 12:21
I got the system() function to execute commands, but the command I want to execute is the massive dsadd command below.
for /F "eol=; tokens=1,2,3,4,5,6,7,8 delims=," %a in (output.txt) do dsadd user "cn=%b %a,ou=Testing,dc=mtmercy,dc=edu" -samid %a%b -fn %a -ln %b -display "%b, %a" -pwd %d -email %a%b@mtmercy.edu -disabled no -empid %c -desc Student
I've had limited success creating users in MS active directory 2003 so I decided to try dsadd. The problem is the quotes that are in the command itself as well as the % signs. The quotes are interpreted by php and the % signs are interpreted wrong in batch files. Any thought on this would be appricated.
dragomirov at tiscali dot it
23-Jan-2006 03:52
IT's great Anthony, your function works even under a *nix machine. You only need to modify like that
<?php
function callTool ($path,$file)
{
chdir($path); $call = $path.$file;
pclose(popen($call.' &', 'r'));
}
?>
The command goes in bakground and the script is still running.
Thanx a lot!
Anthony Catel (paraboul at gmail dot com
09-Jan-2006 07:40
<?php
function system_o($cmd)
{
exec("$cmd", $f);
foreach($f as $output) {
$output = htmlentities($output);
$ret .= "$output\n";
}
return $ret;
}
?>
You can parse the output
afineman at computer dot org
15-Dec-2005 12:09
In response to the comment by 'daniel dot hopp at godot dot de' regarding the use of start-stop-daemon to exec a process within a session:
start-stop-daemon will probably not be a good choice. start-stop-daemon with the --start option will not start the daemon if any matching process is found. In other words, if you are using it to start a process running 'myscript', and there is another instance of 'myscript' found in the process table, start-stop-daemon will *not* start another process and will return 1, unless --oknodo is set.
Check out a man page for start-stop-daemon.
rymfaxe (at) hotmail (dot) com
04-Dec-2005 08:50
Starting batch or exe files (from a local Apache server 1.3.24 with PHP 4.3.1) to be executed within WinXP SP2 and having the program running in background - which certainly is tricky.
I figured this peace of code makes it very possible.
Instead of using exec() I prefered popen() adding the parameter /b which makes it run in the background, thus having PHP script continued to be interpreted contrary to be hanging in the process.
<?php
function callTool ($path,$file) {
chdir($path); $call = $path.$file;
pclose(popen('start /b '.$call.'', 'r'));
}
$location = "c:\path\to\desired\folder";
$filename = "\tool1.exe";
callTool($location,$filename);
$location = "c:\path\to\desired\folder";
$filename = "\tool2.bat";
callTool($location,$filename);
$location = "c:\path\to\desired\folder";
$filename = "\tool3.com";
callTool($location,$filename);
?>
This example assumes that the Apache properties locally has bin told to 'allowe this server to interact with desktop' which on WinXP is to be set under Start > Run > services.msc - next, right click "Apache...", select properties and click on the 'login tab'.
Hope someone to benefit out of this stuff.
valqk at lozenetz dot org
24-Nov-2005 04:05
If you are chrooting php into enviornment that doesn't have /bin/sh you can't execute any command! Even when you call
mail() and it calls sendmail ... well actually sendmail NEVER gets called because /bin/sh is not in the chroot!
SO in conclusion: YOU MUST HAVE /bin/sh TO EXECUTE SOMETHING!!!
VERY IMPORTNAT!
I've lost few days while find this, hope it helps someone!!!
ripat at lumadis dot be
07-Nov-2005 11:54
About the background functions below, many hosting service disable the exec or passthru functions.
It is still possible to run a script in background by sending a 200 OK header to the client
|
|