-2

I have to execute a batch file (I.e. .bat ) and get the result on an HTML page.

I used this PHP code to get a result:

<?php
    echo "<br>";
    $result = shell_exec('start file.bat');
    iconv("CP850","UTF-8",$result);
    echo "<pre>$result </pre>";
?>

Now the problem is that I get a result only when the batch file execution finishes, and I want to have the result in real time, like running via command line.

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
Yaz
  • 492
  • 1
  • 6
  • 20
  • Have you considered moving the commands from the .bat file into the PHP code instead? This would then allow you to echo out the result of each command. – Daniel Samson Feb 08 '17 at 14:39
  • @DanielSamson the same thing , the result is only if cmd finish exect – Yaz Feb 08 '17 at 14:42
  • You need to use a socket based approach forking a process instead of relying on primitive functions like `exec()` and similar. That means you fork a process but communicate with that process via sockets. That allows to forward any output that process creates immediately. But it is much more complex. And actually I am not certain if that is possible the same way under an MS-Windows platform. I only did that a few times on a normal Linux system. – arkascha Feb 08 '17 at 14:42

2 Answers2

0

Found in the comments of the shell_exec documentation's page of PHP

If you're trying to run a command such as "gunzip -t" in shell_exec and getting an empty result, you might need to add 2>&1 to the end of the command, eg:

Won't always work: echo shell_exec("gunzip -c -t $path_to_backup_file");

Should work: echo shell_exec("gunzip -c -t $path_to_backup_file 2>&1");

In the above example, a line break at the beginning of the gunzip output seemed to prevent shell_exec printing anything else. Hope this saves someone else an hour or two.

I believe it is what you really have to do.

Reference: http://php.net/manual/en/function.shell-exec.php#106250

Yann Chabot
  • 4,789
  • 3
  • 39
  • 56
0

As already mentioned in the comments to your question you need to fork a process in such way that you can communicate with it. That is not possible with imple functions like exec() and the like.

Instead take a look at this simple example:

File test.sh:

#!/bin/bash
echo start counting ...
for counter in 1 2 3
do
    echo * counter is at value $counter *
    sleep 3
done
echo ... finished counting.

File test.php:

<?php
$descriptorspec = array(
   0 => array('pipe', 'r'),
   1 => array('pipe', 'w'),
);

echo "forking process ...\n";
$process = proc_open('./test.sh', $descriptorspec, $pipes);

if (is_resource($process)) {
    echo "... successfully forked process ...\n";

    while (!feof($pipes[1])) {
        echo fread($pipes[1], 1024);
        flush();
    }

    echo "... process has finished ...\n";
    fclose($pipes[0]);
    fclose($pipes[1]);
    echo "... pipes closed ...\n";

    proc_close($process);
    echo "... process closed.\n";
} else {
    echo "... failed to fork process!\n";
}

The obvious output of a test run of that php script is:

forking process ...
... successfully forked process ...
start counting ...
* counter is at value 1 *
* counter is at value 2 *
* counter is at value 3 *
... finished counting.
... process has finished ...
... pipes closed ...
... process closed.

But the interesting part here is that this output is not sent in one go once that forked process has finished, but in what you referred to as "a live manner". So the first four lines appear immediately, the next two with a 3 second delay each, then the rest of the output.

Please note that the above example is meant as a demonstration for a Linux CLI environment. So it does not care about html markup but outputs plain text and relies on bash as a shell environment for the forked process. You will have to adapt that simple demonstration to your needs, obviously.

arkascha
  • 41,620
  • 7
  • 58
  • 90