passthru

(PHP 4, PHP 5, PHP 7, PHP 8)

passthru β€” ВыполняСт внСшнюю ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ Π½Π΅ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹ΠΉ Π²Ρ‹Π²ΠΎΠ΄

ОписаниС

function passthru(string $command, int &$result_code = null): ?false

Ѐункция passthru() ΠΏΠΎΡ…ΠΎΠΆΠ° Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ exec() Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ выполняСт ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ command. Π­Ρ‚Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ вмСсто Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ exec() ΠΈΠ»ΠΈ system(), ΠΊΠΎΠ³Π΄Π° Π²Ρ‹Π²ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Unix прСдставляСт собой Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ нСпосрСдствСнно Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΠΎΠ΅ использованиС этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ - Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΈΡ… ΡƒΡ‚ΠΈΠ»ΠΈΡ‚ ΠΊΠ°ΠΊ pbmplus, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ выводят нСпосрСдствСнно ΠΏΠΎΡ‚ΠΎΠΊ изобраТСния. Установив Content-type Π² image/gif ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Π²Π°Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ pbmplus для Π²Ρ‹Π²ΠΎΠ΄Π° gif, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ PHP-скрипты, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ выводят изобраТСния Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€.

Бписок ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²

command

Команда, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ функция.

result_code

Ѐункция Π·Π°ΠΏΠΈΡˆΠ΅Ρ‚ Π² эту ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ статус Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° Unix-ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, Ссли Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ result_code ΠΏΠ΅Ρ€Π΅Π΄Π°Π»ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния

Ѐункция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ null, Ссли Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠ»Π°ΡΡŒ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, ΠΈΠ»ΠΈ false, Ссли Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка.

Ошибки

Ѐункция Π²Ρ‹Π΄Π°Ρ‘Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ уровня E_WARNING, Ссли функция passthru() Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ command.

Ѐункция выбрасываСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ValueError, Ссли ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ command Π½Π΅ ΡƒΠΊΠ°Π·Π°Π»ΠΈ ΠΈΠ»ΠΈ содСрТит Π½ΡƒΠ»Π΅Π²Ρ‹Π΅ Π±Π°ΠΉΡ‚Ρ‹.

Бписок измСнСний

ВСрсия ОписаниС
8.0.0 Если ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ command Π½Π΅ ΡƒΠΊΠ°Π·Π°Π»ΠΈ ΠΈΠ»ΠΈ содСрТит Π½ΡƒΠ»Π΅Π²Ρ‹Π΅ Π±Π°ΠΉΡ‚Ρ‹, функция passthru() Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ выбрасываСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ValueError; Ρ€Π°Π½ΡŒΡˆΠ΅ функция Π²Ρ‹Π΄Π°Π²Π°Π»Π° ΠΎΡˆΠΈΠ±ΠΊΡƒ уровня E_WARNING ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π»Π° false.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ

Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅

ΠšΠΎΠΌΠ°Π½Π΄Ρƒ ΡΠΊΡ€Π°Π½ΠΈΡ€ΡƒΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ escapeshellcmd(), Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ escapeshellarg(), ΠΊΠΎΠ³Π΄Π° Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΡŽΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ ΠΎΠ±ΠΌΠ°Π½ΠΎΠΌ Π½Π΅ заставили систСму Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: ΠŸΡ€ΠΈ запускС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ Π²Ρ‹Π²ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ Π² Ρ„Π°ΠΉΠ» ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π²ΠΎΠ΄Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π»Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅. PHP зависнСт Π΄ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ссли Π½Π΅ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π²Ρ‹Π²ΠΎΠ΄.

Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅

  • exec() - ВыполняСт внСшнюю ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ
  • system() - ВыполняСт внСшнюю ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ Π²Ρ‹Π²ΠΎΠ΄
  • popen() - ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ процСсса
  • escapeshellcmd() - Π­ΠΊΡ€Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚ мСтасимволы ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки
  • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ исполнСния
οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 15 notes

up
17
puppy at cyberpuppy dot org ΒΆ
21 years ago
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.
up
9
jo at durchholz dot org ΒΆ
18 years ago
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.
up
7
igor at bboy dot ru ΒΆ
20 years ago
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.
up
1
divinity76+spam at gmail dot com ΒΆ
3 years ago
if you have problems with passthru("docker-compose ...bash") losing interactive shell size information, try using proc_open instead, for some reason docker-compose bash knows the size of the outer terminal when i use use proc_open, but loses that information when i use passthru,

eg i replaced
<?php
passthru("docker-compose -f docker-compose.yml bash",$ret);
?>
with
<?php
$empty1=array();
$empty2=array();
$proc=proc_open("docker-compose -f docker-compose.yml bash",$empty1,$empty2 );
$ret = proc_close($proc);
?>

and suddenly docker-compose bash knew my terminal size :)
up
1
Zak Estrada ΒΆ
21 years ago
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).
up
1
Stuart Eve ΒΆ
20 years ago
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);
up
0
mail at dtrasbo dot dk ΒΆ
3 years ago
To capture the output of a command in a string without using output buffer functions, use shell_exec()
up
0
tox at novasonica dot com ΒΆ
6 years ago
I was trying to implement a system that allows running arbitrary CLI commands with parameters, but I kept running into the issues with user prompts from the command as they would let execution hang. The solution is simple: just use passthru() as it outputs everything and correctly handles user prompts out of the box.
up
0
myselfasunder at gmail dot com dot dfvuks ΒΆ
15 years ago
PHP's program-execution commands fail miserably when it comes to STDERR, and the proc_open() command doesn't work all that consistently in non-blocking mode under Windows.

This command, although useful, is no different. To form a mechanism that will see/capture both STDOUT and STDERR output, pipe the command to the 'tee' command (which can be found for Windows), and wrap the whole thing in output buffering.

Dustin Oprea
up
0
Chroot ΒΆ
17 years ago
If you have chrooted apache and php, you will also want to put /bin/sh into the chrooted environment. Otherwise, the exec() or passthru() will not function properly, and will produce error code 127, file not found.
up
0
sarel dot w at envent dot co dot za ΒΆ
21 years ago
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.
up
0
swbrown at ucsd dot edu ΒΆ
23 years ago
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.
up
-1
nuker at list dot ru ΒΆ
20 years ago
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;
?>
up
-1
kpierre at fit dot edu ΒΆ
24 years ago
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
up
-3
stuartc1 at NOSPAM dot hotmail dot com ΒΆ
20 years ago
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().