exec

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

exec β€” ВыполняСт внСшнюю ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ

ОписаниС

function exec(string $command, array &$output = null, int &$result_code = null): string|false

Ѐункция exec() выполняСт ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ command.

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

command

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

output

Ѐункция Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ массив строками Π²Ρ‹Π²ΠΎΠ΄Π° ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, Ссли Π² спискС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π΄Π°Π»ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ для ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° output. Ѐункция Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ Π² массив ΠΏΡ€ΠΎΠ±Π΅Π»ΡŒΠ½Ρ‹Π΅ символы Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ \n, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‚ строки. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: функция exec() Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ Π½ΠΎΠ²Ρ‹Π΅ элСмСнты Π² ΠΊΠΎΠ½Π΅Ρ† массива, Ссли массив ΡƒΠΆΠ΅ содСрТит элСмСнты. ΠŸΠ΅Ρ€Π΅Π΄ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ΠΉ элСмСнтов Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ exec() Π½Π° массивС Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ ΡΠ·Ρ‹ΠΊΠΎΠ²ΡƒΡŽ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ unset(), Ссли Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ элСмСнты Π² ΠΊΠΎΠ½Π΅Ρ† массива Π½Π΅ трСбуСтся.

result_code

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

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

Ѐункция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ послСднюю строку ΠΈΠ· Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹. Ѐункция passthru() ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚, ΠΊΠΎΠ³Π΄Π° трСбуСтся Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ ΠΈ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ сырыС Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π±Π΅Π· посрСдников.

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

Ѐункция Π²Π΅Ρ€Π½Ρ‘Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ Π²Ρ‹Π²ΠΎΠ΄Π° ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, которая Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠ»Π°ΡΡŒ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли установили ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ output.

Ошибки

Выдаётся ошибка уровня E_WARNING, Ссли функция exec() Π½Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠ»Π° ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ command.

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

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

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

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #1 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ выполнСния внСшнСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ exec()

<?php

// Π’Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ запустили процСсс php/httpd
// (ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎ ΠΊ систСмам с ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ whoami Π² систСмном ΠΏΡƒΡ‚ΠΈ)
$output = null;
$retval = null;
exec('whoami', $output, $retval);
echo
"Команда Π²Π΅Ρ€Π½Ρ‘Ρ‚ статус $retval ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅:\n";
print_r($output);

?>

Π’Ρ‹Π²ΠΎΠ΄ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΡ…ΠΎΠΆ Π½Π°:

Команда Π²Π΅Ρ€Π½Ρ‘Ρ‚ статус 0 ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅:
Array
(
    [0] => cmb
)

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

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

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

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

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: Π’ Windows функция exec() запускаСт ΠΊΠΎΠΌΠ°Π½Π΄Π½ΡƒΡŽ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΡƒ cmd.exe, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ. Π’Π½Π΅ΡˆΠ½ΡŽΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π±Π΅Π· запуска ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ cmd.exe Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ proc_open() с ΠΎΠΏΡ†ΠΈΠ΅ΠΉ bypass_shell.

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

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

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

up
198
Arno van den Brink ΒΆ
17 years ago
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(), 0, 7) == "Windows"){
        pclose(popen("start /B ". $cmd, "r"));  
    }
    else {
        exec($cmd . " > /dev/null &");   
    }
}
?>
up
18
tsmtgdi at gmail dot com ΒΆ
2 years ago
Please be aware that EXEC ignore the stderr!

So something like

mkdir /impossible path

Will fail, and show nothing, you must use

mkdir /impossible 2>&1 

to properly capture the error message

ELSE
if executed in CLI, will just print on the terminal, if executed on a browser is lost.

I strongly suggested those notes to be added in the main description, and not lost in a comment at the bottom.
up
82
dell_petter at hotmail dot com ΒΆ
17 years ago
(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;
    }
}
?>
up
49
Simon ΒΆ
11 years ago
Can’t get the output from your exec’d command to appear in the $output array?
Is it echo’ing all over your shell instead?

Append "2>&1" to the end of your command, for example:

exec("xmllint --noout ~/desktop/test.xml 2>&1", $retArr, $retVal);

Will fill the array $retArr with the expected output; one line per array key.
up
3
php dot reg at kjpetrie dot co dot uk ΒΆ
3 years ago
If you want to run the command in the background and also use escapeshellcmd() as recommended, ensure you do the redirection outside the brackets! These are things you do want the shell to interpret.

E.g. exec(escapeshellcmd('mycommand and arguments').' > /dev/null &');
up
28
msheakoski @t yahoo d@t com ΒΆ
21 years ago
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", 7, false);
?>

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

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", 3, true);
?>

For more info on the Run() method go to:
http://msdn.microsoft.com/library/en-us/script56/html/wsMthRun.asp
up
10
Farhad Malekpour ΒΆ
18 years ago
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.
up
3
elwiz at 3e dot pl ΒΆ
15 years ago
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();

?>
up
3
Bob-PHP at HamsterRepublic dot com ΒΆ
20 years ago
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.
up
4
Paul Sommer ΒΆ
10 years ago
I tried to execute a command in background under Windows.
After struggling for hours with all these half ready examples I would like to share the syntax I found working (for windows at least). This is not tested under Linux as there are more elegant ways to spawn a process.

Based on  the function from Arno van den Brink.

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

This works perfectly with e.g.
<?php
execInBackground('del c:\tmp\*.*') 
?>

but the following does NOT work:
<?php
execInBackground('\"c:\path with spaces\my program.exe\"') 
?>

Why?
When windows sees quotation marks (\") it thinks this is the window title, not the command.
So, when your command needs quotation marks you HAVE TO provide a window name first, like
execInBackground("\"title\"" "\"c:\path with spaces\my program.exe\") 

Quotation marks are mandatiory for window title. Otherwise windows thinks this is the program name.

Weired, but "Hey! it's Windows!" :)
up
3
Hypolite Petovan ΒΆ
6 years ago
On Unix, to execute a command $cmd in the background, the one and only allowed standard output redirection syntax is "> /path/to/file &". No other valid standard output redirection syntax will allow a command to be ran in the background.

<?php
// The following will be ran in the background
exec($cmd . " > /path/to/file &"); 

// All the following will NOT be ran in the background
exec($cmd . " >> /path/to/file &"); 
exec($cmd . " &> /path/to/file &"); 
exec($cmd . " &>> /path/to/file &"); 
exec($cmd . " 2>&1 > /path/to/file &"); 
exec($cmd . " 2>&1 >> /path/to/file &"); 
?>
up
3
juan at laluca dot com ΒΆ
15 years ago
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
up
2
hans at internit dot NO_SPAM dot com ΒΆ
24 years ago
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!
up
0
no at mail dot com ΒΆ
3 years ago
<this note copied from system page>
This is for WINDOWS users. I am running apache and I have been trying for hours now to capture the output of a command.

I'd tried everything that is written here and then continued searching online with no luck at all. The output of the command was never captured. All I got was an empty array.

Finally, I found a comment in a blog by a certain amazing guy that solved my problems.

Adding the string ' 2>&1' to the command name finally returned the output!! This works in exec() as well as system() in PHP since it uses stream redirection to redirect the output to the correct place!
<?php
exec("yourCommandName 2>&1", $output);
var_dump($output);
?>
up
2
Martin Lakes ΒΆ
15 years ago
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!
up
-1
mamedul.github.io ΒΆ
2 years ago
Cross function solutions for execute command using PHP-

function php_exec( $cmd ){

    if( function_exists('exec') ){
        $output = array();
        $return_var = 0;
        exec($cmd, $output, $return_var);
        return implode( " ", array_values($output) );
    }else if( function_exists('shell_exec') ){
        return shell_exec($cmd);
    }else if( function_exists('system') ){
        $return_var = 0;
        return system($cmd, $return_var);
    }else if( function_exists('passthru') ){
        $return_var = 0;
        ob_start();
        passthru($cmd, $return_var);
        $output = ob_get_contents();
        ob_end_clean(); //Use this instead of ob_flush()
        return $output;
    }else  if( function_exists('proc_open') ){
        $proc=proc_open($cmd,
            array(
                array("pipe","r"),
                array("pipe","w"),
                array("pipe","w")
            ),
            $pipes);
        return stream_get_contents($pipes[1]);
    }else{
        return "@PHP_COMMAND_NOT_SUPPORT";
    }    

}
up
0
krjdev at gmail dot com ΒΆ
4 years ago
Note for OpenBSD users:

In the default configuration from OpenBSD, PHP runs into a chroot. So the exec() command will not work. You will get a 127 (command not found) result code. The reason is, the shell (/bin/sh) is missing in chroot, but the exec() command requires the shell.

A quick and dirty solution is to copy /bin/sh (which is statically linked) in the chroot directory:
<?php
$ cp /bin/sh /var/www/bin
?>

(I have noticed this on OpenBSD 7.0 with PHP 8.0.11.)
up
0
ivk ΒΆ
5 years ago
result_code -1 could mean "Maximum number of file descriptors reached". Check count(get_resources('stream')) and ulimit -Sn
up
0
alvaro at demogracia dot com ΒΆ
15 years ago
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).
up
-1
dr_jones153 at hotmail dot com ΒΆ
18 years ago
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.
up
-1
layton at layton dot tk ΒΆ
21 years ago
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.
up
-4
bahri at bahri dot info ΒΆ
17 years ago
[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);
    }
?>