User Contributed Notes Ex�cution de programmes externes |
|
[email protected]
04-Jun-1999 10:39 |
|
Wondering, why your command isn�t printing anything?
Perhaps
your command fails? But why isn�t there any error message in your
browser?
Under Unix the error ouput goes into another
filehandle. Use this "trick" to see your
errors:
<PRE>
system("touch /forbidden
2>&1");
</PRE>
This will pipe any output from
ERROROUT into STDOUT (works with most shells, see docs of used shell, if
this isn�t working).
|
|
nemo
03-Aug-1999 06:00 |
|
On the off chance you always get the same return value (in my case 11,
although it may differ) when you call <code>passthru</code>,
or <code>exec</code>, you may want to investigate the
possibility that the desired command is segfaulting during the
<code>exec</code>.
Writing text out at the very start
does not always work: the pipes aren't always emptied.
If you want to know about a few return values, check out
the man page for <code>sh</code>.
|
|
[email protected]
01-Dec-1999 04:32 |
|
For anyone interested in execing in the background I figured out how to do
it. I wrote a
small C program (You can see it at )
that forks a process and closes off STDIN,STDOUT,STDERR).. then all you
do is call exec with: exec("/path/to/mikehup whatever &");
and PHP will come back and your process will run in the background :)
this is the only way i've been able to do it...
|
|
[email protected]
22-Jan-2000 11:00 |
|
These functions all execute the given command in a shell, so standard shell
redirection, command sequencing, piping, etc. can be
used.
There appears to be no way to execute a command, feed it
stuff on standard in, and retreive the return code and the output sent to
standard out (not to mention standard error). You can try writing a
wrapper for the command that you wish to execute, one that takes an
argument to be used as standard in. Then use exec() to execute it and
capture standard out and the return code. But don't do this with
passwords because the password will be visible to anybody doing a
"ps" command.
If you're having trouble creating or
modifying files, it's probably a permission problem. Your code is running
as the webserver; a user that has few permissions.
|
|
php-doc at tracking.wunsch.org
01-Sep-2000 05:32 |
|
Check out the popen function if you want to send data to the standard input
of the command you execute, or you want to be able to read its standard
output.
|
|
[email protected]
17-Oct-2000 12:29 |
|
For anybody confused from a C/Perl background:
PHP's exec() and
system() calls really have no relation to what you might expect (replace
current process vs.
wait for child process). PHP's exec($command,
$array, $result) thus equals a C-style system().
|
|
[email protected]
02-Apr-2001 02:41 |
|
Note that *none* of the Program Executions functions work under Windows 98
using PHP4.0.3pl1 and Personal Web Server. I repeatedly get 'Unable to
fork' warnings with no execution of the external calls.
|
|
[email protected]
23-Apr-2001 11:23 |
|
Well, now it is possible to put the process to background also on
Win98:
I wrote (modified from a ready source :) this little program in
C/C++ called bgrun:
www.jukkis.net/bgrun/bgrun.exe
or
www.jukkis.net/bgrun/bgrun.cpp
I really have no idea what
i was doing when i wrote it, i believe it leaves open the stderr, stdin
and stdout (BAD thing..)
but as it works for me (opens winamp without
crashing the whole system) I really don't care...
If someone
wants to clean up the code, please go ahead.
/jukkis.
|
|
[email protected]
21-Jun-2001 01:09 |
|
There is a problem by the function exec() and PHP4 under Windows. If you
don't get the results line(s) it is possible, that the process hasn't an
own console. For IIS 4.0 for example you can switch, that each process get
an own console, with following:
1. open a DOS-Box and go to the
directory
"..\winnt\system32\inetsrv\adminsamples"
2. give the
following command
"adsutil set w3svc/CreateCGIWithNewConsole
1"
|
|
[email protected]
15-Aug-2001 08:17 |
|
Anyone who still wants a copy of mikehup.c,
I rewrote it:
This
program will help you run programs in the
background that are called
with the php system()
function.
|
|
[email protected]
22-Aug-2001 11:00 |
|
I found a way to get a userlist (users logged in at Novell or NT) into a
PHP-script. Because executing commands from PHP seems a lot of trouble i
made a bat-file being executed every hour on the server. In the bat-file i
put: nlist user /a >> aaa.txt Now, from PHP you can easily read the
aaa-file and there you are, all user in your PHP-script!
|
|
phobo_AT_paradise.net.nz
04-Sep-2001 01:31 |
|
If you're looking for a command to run PHP code from a string, use
eval().
This is great for caching semi-dynamic webpages, or to
have a .php website with much of it's source in a database...
|
|
[email protected]
25-Oct-2001 09:05 |
|
To keep a program running in the background on win98 the
command
exec("COMMAND.COM /C START program args
>NUL");
works fine for me.
|
|
[email protected]
16-Jan-2002 09:55 |
|
This note is regard php scripts hanging when running system commands in the
background until background process completes. If you have redirected
system command output and PHP still waits around until background process
completes...check if you are using PHP session handlers. If you have used
a start_session() before your exec() look into session_write_close()
...sessions use files to store session data on ther server to relate to
cookies...for some strange reason this open file handler causes PHP
scripts to hang until background completetions...I would think only the
file handlers for the system command output would need to be delt with but
?! FreeBSD, Apache mod, PHP 4.1.1 Cheers, Ian
Carlson [email protected]
|
|
[email protected]
23-Jan-2002 09:47 |
|
If you are using sessions and want to start a background process, you might
have the following problem: The first time you call your script
everything goes fine, but when you call it again and the process is STILL
running, your script seems to "freeze" until you kill the
process you started the first time.
You'll have to call
session_write_close(); to solve this problem. It has something to do with
the fact that only one script/process can operate at once on a session.
(others will be lockedout until the script finishes)
I don't know
why it somehow seems to be influenced by background processes, but I tried
everything and this is the only solution. (i had a perl script that
"daemonized" it's self like the example in the perl
manuals)
Took me a long time to figure out, thanks [email protected]!
:-)
|
|
[email protected]
01-Feb-2002 05:25 |
|
Re: session_write_close()
To launch a background process within a
session, I recommend to use a start-stop-daemon and ship parameters via
ENV.
Example: ---------------------------------------- <?php
// Within a session.. exec("/some/where/launch.sh
300"); // ..finished
immediately. ?>
---------------------------------------- #!/bin/bash #
/some/where/launch.sh T=$1 export
T DAEMON=/some/where/runme.pl start-stop-daemon --start --quiet
--background --exec
$DAEMON
---------------------------------------- #!/usr/bin/perl #
/some/where/runme.pl my $t =
$ENV{'T'}; sleep($t);
----------------------------------------
|
|
[email protected]
10-Feb-2002 06:09 |
|
// If you need to get both the exit status and the return value of //
exec it seems PHP's exec command is broken - at least on my // system.
It does not return the exit status of the process // reliably, but
always -1... Here is a workaround...
// I'm running php v. 4.0.4pl1
on Linux SuSE 7.2 (from command line // and/or under apache)
//
Here is an example of the broken stuff in exec:
// This next should
work: $lines=array();$errco=0; $result = exec("ls -l /tmp
2>&1",$lines,$errco); echo "Errco: " . $errco .
"\n"; echo "Result: " . $result .
"\n\n";
// and this shouldn't (there is no such file as
/tm $lines=array();$errco=0; $result = exec("ls -l /tm
2>&1",$lines,$errco); echo "FailErrco: " . $errco
. "\n"; echo "FailResult: " . $result .
"\n\n";
/* This outputs:
Errco: -1 Result:
-rw-r--r-- 1 root root 9670 Dec 21 18:27
xwlog
FailErrco: -1 FailResult: ls: /tm: No such file or
directory
And the errco is always -1. From the command line, $?
is 0, then 1 but never -1... Hmm... */
// This function
returns the status (more) reliably. There are many // commands that can
break it. E.g. if $cmd doesn't finish with a // newline... If $cmd
spawns a process that prints output // asynchronously (i.e. after the
echo $?). There are probably many // more.. But if you know that
command your calling (I wrote mine // myself), it can work...
//
It is called same way as exec... function myExec($_cmd, &$lines,
&$errco) { $cmd = "$_cmd ; echo $?"; exec($cmd,
$lines); // Get rid of the last errco line... $errco = (integer)
array_pop($lines); if (count($lines) == 0) { return
""; } else { return $lines[count($lines) - 1];
} }
// this should work $lines=array();$errco=0; $result =
myExec("ls -l /tmp 2>&1",$lines,$errco); echo
"myErrco: " . $errco . "\n"; echo "myResult:
" . $result . "\n\n";
// and this
shouldn't $lines=array();$errco=0; $result = myExec("ls -l /tm
2>&1",$lines,$errco); echo "myFailErrco: " .
$errco . "\n"; echo "myFailResult: " . $result .
"\n\n";
/* This outputs:
myErrco:
0 myResult: -rw-r--r-- 1 root root 9670 Dec 21 18:27
xwlog
myFailErrco: 1 myFailResult: ls: /tm: No such file or
directory
So now I can test for whether a command succeeded or
failed... Hope it helps someone.
*/
|
|
[email protected]
10-Feb-2002 06:41 |
|
If you try to execute a 16-bit console application on Win95/98, the script
hangs. The solution is to use a 32-bit console application that calls
the 16-bit app with the requested parameters, and that will work
ok.
The code for such a stub-app can easily be found on the MS
site: just Google with '16-bit console windows' and feel lucky :-) (or
try Q150956 directly :)
|
|
[email protected]
02-Mar-2002 08:14 |
|
windows y2k does work .. just make sure you double backslash
everything eg.
to rotate an image 90 degrees in imagemagic which
is in c:\imagemagic on a file image36.jpg in
f:\wwwroot\web\images\gallery3 you would write
<?
$command="C:\\imagemagick\\convert -rotate 90
f:\\wwwroot\\web\\images\\gallery3\\image36.jpg
f:\\\wwwroot\\web\\images\\gallery3\\image36.jpg";
exec("$command"); ?>
|
|
[email protected]
22-Mar-2002 12:36 |
|
Simple way to encrypt a password using
htpasswd.exe.
$anyname="/path/htpasswd -nb $username
$password";
$somename=exec($anyname);
eg.For
windows $command="c:\apache\bin\htpasswd.exe -nb $username
$password";
$encrypt=exec($command);
|
|
[email protected]
05-Apr-2002 11:17 |
|
For those who want to execute a .php script to run in the background, from
a .php web page...
exec("php script.php parameters
2>dev/null >&- <&- >/dev/null
&");
Where... - php is the path to your php script
executer (php has to be specifically complied to be to do this) -
script.php is the script - parameters are none or more parameters -
2>dev/null redirects the stderr to a file - <&- switches off
the stdin - >&- switches off the stdout - >dev/null
redirects all other output to the file dev/null - & direct script
to run in background
This is the only way I managed to get it
working (Linux & Apache, php 4x enviroment) . What is also great is
that the process is forked so even though a user may close the browser
that initiated the exec(), the process will still run to completion. And
the dev/null file can be turned into a log.
What I found odd is
that the script I was execing would run fine in the bg when executed from
the command line, but not from the browser until I closed the stdin and
stdout.
|
|
[email protected]
11-Apr-2002 11:45 |
|
In case you ever had to chain from php to another program (e.g. with a cgi
php that only gives part of the output, or with php-gtk), here is a little
C program that kills his parent (php, for instance), then launches a
program given in argument.
chain.c :
#include
<unistd.h>
int main(int argc, char**argv) { /* kill the
parent */ kill(getppid(), 15); argv++; /* then launch the
new program */ return execvp(argv[0], argv); } (compile with
gcc -O3 -o chain chain.c) then in php, use <? exec('chain sh
-c echo test'); ?>
|
|
Curt
12-Jun-2002 07:34 |
|
if you use session_write_close() in order to exec in the background, you
can use session_start() to "turn on" the session
again:
session_write_close(); exec(mycommand >/dev/null
&); session_start();
|
|
[email protected]
17-Jun-2002 11:51 |
|
In handing over a parameter to such a background program, I succeeded with
the following syntax:
exec("QUERY_STRING='campaign=$campaign';
export QUERY_STRING; php campaign_exec.php &");
|
|
[email protected]
22-Jun-2002 12:37 |
|
Instead of getting the whole package of load average and date, get only the
days of uptime! Use this code:
$uptime = exec("expr $(awk
'{print $1}' < /proc/uptime | awk -F. '{print $1}' ) /
86400"); print("Uptime: $uptime days");
This will
print "Uptime x days"!
|
|
[email protected]
26-Jun-2002 07:03 |
|
I needed to know when a group of background tasks, which had been launched
with a call to system, had terminated. I could not find a function to
call, so I created a little function.
It basically loops on the
existance of a string in the results returned by the command
ps.
All my commands, which run in background have the pid returned
by posix_getpid in them.
I am able to launch many background task
and effectively wait for them all to finish.
Before this, I would
basically would sleep for N seconds.
I apologise if a well known or
better method exist.
Thanks, The New
Bee =============== ===============
function
wait_until_termination ($id, $duration){ $i = 0;
do { $i += 1;
$cnt = `ps -auxww | grep $id
| grep -v grep |
awk '{print $2}' | grep -v
$id| wc -l` ;
if ($cnt > 0) { sleep
($duration); }
} while
($cnt != 0);
echo ("wait_until_termination
(PID: $id, SEC: $duration) : LOOPS :$i "); }
|
|
[email protected]
26-Jun-2002 07:05 |
|
I needed to know when a group of background tasks, which had been launched
with a call to system, had terminated. I could not find a function to
call, so I created a little function.
It basically loops on the
existance of a string in the results returned by the command
ps.
All my commands, which run in background have the pid returned
by posix_getpid in them.
I am able to launch many background task
and effectively wait for them all to finish.
Before this, I would
basically would sleep for N seconds.
I apologise if a well known or
better method exist.
Thanks, The New
Bee =============== ===============
function
wait_until_termination ($id, $duration){ $i = 0;
do { $i += 1;
$cnt = `ps -auxww | grep $id
| grep -v grep |
awk '{print $2}' | grep -v
$id| wc -l` ;
if ($cnt > 0) { sleep
($duration); }
} while
($cnt != 0);
echo ("wait_until_termination
(PID: $id, SEC: $duration) : LOOPS :$i "); }
|
|
[email protected]
30-Jun-2002 06:41 |
|
to execute a script in background from php you don't need to use mikehup or
other tools. just do:
`/usr/bin/php -q foobar.php >/dev/null
2>&1 &`;
mat
|
|
[email protected]
01-Jul-2002 10:00 |
|
I've been trying to write a process threader in PHP and I couldn't for the
life of me get system(), exec() or and of the command functions to
sucessfully execute a "lynx -dump" command. It worked fine from
the command line, but not from within a php page.
I ended up using
the "wget" command (with the background option) to do it, then
removed it's log. It's messy, but it works.
exec("wget '
-b -O wget-log-1 >&- <&- >/dev/null
&"); exec("wget '
-b -O wget-log-2 >&- <&- >/dev/null
&"); exec("wget '
-b -O wget-log-3 >&- <&- >/dev/null
&"); exec("wget '
-b -O wget-log-4 >&- <&- >/dev/null
&");
Good Luck...
|
|
[email protected]
13-Jul-2002 02:58 |
|
For Windows Users:
Keep in mind that a lot of UNABLE TO FORK Errors
are the result of insufficient permissions.
CMD.EXE, TEMP
Directory (or whatever you specified in php.ini), and all the directories
that you use to upload o manipulate your files need to have Write
privileges� usually user USER.
This will be useful for all the
people who use GD Libraries or other programs that manipulate graphic
images.
|
|
[email protected]
17-Jul-2002 07:12 |
|
I have tried all the system() shell_exec, adn exec(), and they all seem to
run my in 'in the background'. Is there a way to my app normally. Like so
that it take take focus and run like i opened it myself?
|
|
[email protected]
08-Aug-2002 05:49 |
|
Such a long-winded page, this. But none offered anything useful to me. I
needed to execute a simple command, which works at the shell prompt but
does not work through the PHP exec. If you do this:
----------
CODE ------------
$result = exec ("ls -ali");
---------- /CODE ------------
and find that your
variable contains nothing, don't be surprised. Try this instead:
---------- CODE ------------
exec ("ls -ali",
$resultArray); reset($resultArray); while (list ($key,
$val) = each ($resultArray)) { $resultLines .=
"\n" . trim($val); }
---------- /CODE
------------
The variable "resultLines" will contain all
the results. Hope this helps someone.
|
|
[email protected]
10-Aug-2002 07:47 |
|
(In addition to an older comment)
I had the requirement to start a
program from a php cli-script with a low priority (to run for hours in the
background). I found this to be working fine:
$res=exec("start
/low /b /wait identify.exe -format \"%w %h %m\"
\"".$file."\"");
|
|
[email protected]
12-Aug-2002 08:52 |
|
AFICT, the standard Unix Apache configuration causes an rare problem when
running a job in the background. The MaxRequestsPerChild directive causes
the child to terminate after 1000 requests, any background processes
associated with the child will die with the child unless they are started
with the "nohup" command. Thus, the proper way to start a job
in the background is to use:
exec('nohup my-command > /dev/null
2>&1 &')
|
|
|