Note to Paul Giblock: the command *is* run through the shell.
You can verify this on any Linux system with
<?php
passthru ('echo $PATH');
?>
You'll get the content of the PATH environment variable, not the string $PATH.
passthru
(PHP 4, PHP 5)
passthru — Führt ein externes Programm aus und zeigt dessen Ausgabe an
Beschreibung
Die Funktion passthru() ähnelt der Funktion exec(), da sie ebenfalls ein command ausführt. Diese Funktion sollte anstelle von exec() bzw. system() verwendet werden, wenn die Ausgabe des Unixkommandos binäre Daten erzeugt, die direkt an den Browser zurückgegeben werden sollen. Ein praktisches Beispiel hierfür ist die Ausführung des pbmplus-Utilities, welches einen Bildstream direkt ausgibt. Wenn Sie den Content-Type auf image/gif setzen und dann das pbmplus-Programm aufrufen, um ein GIF zu erzeugen, können Sie auf diesem Weg mittels PHP direkt ein Bild erzeugen und ausgeben.
Parameter-Liste
- command
-
Das auszuführende Programm.
- return_var
-
Ist der Parameter return_var angegeben, wird der Rückgabestatus des UNIX-Befehls hier abgelegt.
Rückgabewerte
Es wird kein Wert zurückgegeben.
Anmerkungen
Falls Sie es erlauben, dass Daten von Usereingaben an diese Funktion weitergereicht werden, sollten Sie escapeshellarg() oder escapeshellcmd() verwenden. Bei Verwendung dieser Funktionen stellen Sie sicher, dass kein Benutzer Ihr System überlisten kann beliebige Kommandos auszuführen
Hinweis: Falls Sie diese Funktion benutzen, um ein Programm zu starten und im Hintergrund weiterlaufen lassen möchten, müssen Sie sicherstellen, dass die Ausgabe des Programms in eine Datei oder einen anderen Ausgabestream umgeleitet wird. Anderenfalls wird PHP solange hängen, bis das Programm zu Ende ausgeführt wurde.
Hinweis: Mit aktiviertem Safe Mode können Sie nur Programme ausführen, die im Verzeichnis liegen, das mit safe_mode_exec_dir angegeben wurde. Aus praktischen Gründen ist es gegenwärtig nicht erlaubt, dass der Pfad zu einem Programm .. enthält.
Mit aktiviertem Safe Mode wird der Kommandostring mit escapeshellcmd() codiert. Deshalb wird echo y | echo x zu echo "y | echo x".
passthru
22-Nov-2007 09:17
18-May-2007 08:30
Stuart:
The pasthru function does not execute the program through the shell. What this mean, among other things, is that your PATH variable is never set. Therefore, you have to use full paths on everything.
I believe system() will run your program underneith a shell. This allow the program to run in a 'normal' environment.
-Paul
03-Jan-2006 02:51
I wrote function, that gets proxy server value from the Internet Explorer (from
registry). It was tested in Windows XP Pro
(Sorry for my English)
<?php
function getProxyFromIE()
{
exec("reg query \"HKEY_CURRENT_USER\Software\Microsoft".
"\Windows\CurrentVersion\Internet Settings\" /v ProxyEnable",
$proxyenable,$proxyenable_status);
exec("reg query \"HKEY_CURRENT_USER\Software\Microsoft".
"\Windows\CurrentVersion\Internet Settings\" /v ProxyServer",
$proxyserver);
if($proxyenable_status!=0)
return false; #Can't access the registry! Very very bad...
else
{
$enabled=substr($proxyenable[4],-1,1);
if($enabled==0)
return false;
else
{
$proxy=ereg_replace("^[ \t]{1,10}ProxyServer\tREG_SZ[ \t]{1,20}","",
$proxyserver[4]);
if(ereg("[\=\;]",$proxy))
{
$proxy=explode(";",$proxy);
foreach($proxy as $i => $v)
{
if(ereg("http",$v))
{
$proxy=str_replace("http=","",$v);
break;
}
}
if(@!ereg("^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:".
"[0-9]{1,5}$",$proxy))
return false;
else
return $proxy;
}
else
return $proxy;
}
}
}
?>
Note, that this function returns FALSE if proxy is disabled in Internet
Explorer. This function returns ONLY HTTP proxy server.
Usage:
<?php
$proxy=getProxyFromIE();
if(!$proxy)
echo "Can't get proxy!";
else
echo $proxy;
?>
08-Dec-2005 08:24
I dunno if anyone else might find this useful, but when I was trying to use the passthru() command on Suse9.3 I was having no success with the command:
$command = 'gdal_translate blahahahaha';
passthru($command);
It only worked once I put:
$command = '/usr/bin/local/gdal_translate blalalala';
passthru($command);
13-Oct-2005 12:09
I had an issue when i used exec
I think we were echoing information on the test.php script.
for eg: when we tried
exec(php test.php,$array,$error);
the return was 127 and the code was failing.
checking the note on this page gave us a hint to use passthru instead.
The only thing to note is that you need to provide the fuull path.
now our command became
passthru(/bin/php /pathtotest/test.php,$array,$error);
this works.
yipeee!!!!!
22-Sep-2005 04:59
When upgrading my redhat server to enterprise 4, selinux was turned on. This caused one of my php scripts (that uses passthru) to fail. After some nice help from redhat, I was able to get the script running again. Here is what helped me.
If you get permission errors (in /var/log/httpd/error_log) which seem to be from selinux (and not standard chmod or chown issues), make sure that the folder you are using is not in /tmp and has the selinux context of httpd_sys_script_rw_t as can be set as follows:
chcon -t httpd_sys_script_rw_t folder_name
Hope this helps someone...
09-Aug-2005 04:52
Thought it might beuseful to note the passthru seems to supress error messages whilst being run in Dos on Windows (test on NT).
To show FULL raw output including errors, use system().
23-Jun-2005 10:33
If you are using passthru() to download files (for dynamically generated content or something outside webserver root) using similar code:
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"myfile.zip\"");
header("Content-Length: 11111");
passthru("cat myfile.zip",$err);
and your download goes fine, but subsequent downloads / link clicks are screwed up, with headers and binary data being all over the website, try putting
exit();
after the passthrough. This will exit the script after the download is done and will not interfere with any future actions.
09-Mar-2005 08:33
Zak Estrada
14-Dec-2004 11:21
Remember to use the full path (IE '/usr/local/bin/foo' instead of 'foo') when using passthru, otherwise you'll get an exit code of 127 (command not found).
Remember, you'll also get this error if your file does not have executable permission.
02-Mar-2005 11:50
Regarding swbrown's comment...you need to use an output buffer if you don't want the data displayed.
For example:
ob_start();
passthru("<i>command</i>");
$var = ob_get_contents();
ob_end_clean(); //Use this instead of ob_flush()
This gets all the output from the command, and exits without sending any data to stdout.
14-Dec-2004 05:21
Remember to use the full path (IE '/usr/local/bin/foo' instead of 'foo') when using passthru, otherwise you'll get an exit code of 127 (command not found).
27-May-2004 05:30
Regarding kpierre's post, be mindful that if you shell script errors, you will find the error output from it in the base error_log file (not virtualhost error_log) in apache.
04-Sep-2003 08:23
With apache 2.x on RH9 passthru() writes 1 byte at a time. Apache 2.x buffers and chunk encodes the output for you - but the chunked encoding devides the output in chunks of 1 byte each...thus several bytes of overhead per byte. I guess that buffering behaviour is by design - but caused problems for me with IE adobe acrobot 5 plugin. The plugin doesn't like like it if you send it a stream of 1 byte chunks - it tells you your file is not a pdf or gives a blank screen. Using output buffering (ob_start / ob_endflush) gives reasonable size chunks and the plugin works OK.
04-Jun-2003 05:41
passthru() seems absolutely determined to buffer output no matter what you do, even with ob_implicit_flush(). The solution seems to be to use popen() instead.
30-Jan-2002 04:35
The documention does not mention that passthru() will only display standard output and not standard error.
If you are running a script you can pipe the STDERR to STDOUT by doing
exec 2>&1
Eg. the script below will actually print something with the passthru() function...
#!/bin/sh
exec 2>&1
ulimit -t 60
cat nosuchfile.txt
03-Oct-2001 04:51
If you sometimes get no output from passthru() use system() instead. This solved this problem for me (php 4.0.5 on Tru64 Unix compiled with gcc).
21-Jun-2001 02:25
PJ's ulimit example is nice; however, if you include multiple commands in the script after the ulimit command, each gets its own, seperate 60 second time slot!<br>
Furthermore, these sixty seconds are *CPU* time. Most programs hang for other reasons than CPU hogging (for example, waiting for a database connection) so for most purposes the number 60 is rather too high.<br>
Try "ulimit -t 1" first, which will give you about 10^9 cycles on modern hardware -- quite enough to get a lot of work done!
15-Feb-2001 02:06
About the problem of zombies, you may call a bash script like this:
--------------------------
#! /bin/bash
ulimit -t 60
<your command here>
--------------------------
