I have a PHP script which prints the output of a bash script (actually it is an expect script), which looks like this:
<?php
ob_implicit_flush(true);
ob_end_flush();
$cmd = "./expect_script.sh";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo '<pre>';
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
}
}
echo '</pre>';
?>
So I wanted to get the real time output with automatic scroll at the end of the page with every new line appearance and I found this: printing process output in realtime
Then I added the proposed html code to my script as follows:
<html><head>
<script language="javascript">
var int = self.setInterval("window.scrollBy(0,1000);", 200);
</script>
</head>
<body>
<?php
ob_implicit_flush(true);
ob_end_flush();
$cmd = "./expect_script.sh";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo '<pre>';
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
}
}
echo '</pre>';
?>
</body>
</html>
However, when script finishes the web browser won't let me browse to the top of the page because it is still scrolling to the bottom.
How shall avoid it so that I can browse once the script is finished?
you are using setInterval to repeat some task and never ask it to stop that.
you will need to stop setInterval from repeating itself , at the end of your php code add :
echo '</pre>';
echo '<script language="javascript">self.clearInterval(int);</script>';
also you will need to close your proc process :
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
}
proc_close($process);
}
Related
I've been trying to figure out why I can't get NMap to give me any sort of output nor even work for that matter via PHP.
Things I've tried so far:
// this doesn't return anything because it's wrong
$output = passthru('nmap -V');
echo $output;
// this returns a negated integer value
passthru('nmap -V', $output);
echo $output;
// this doesn't return anything either
$stream = popen('C:\nmap -V', 'r');
while (!feof($stream))
{
$buffer = fread($stream, 1024);
echo $buffer;
}
pclose($stream);
// this doesn't do anything as well
$output = system('C:\nmap -V');
echo $output;
// this does nothing also...
ob_start(); // start output buffering
fpassthru('C:\nmap -V'); // flush COMPLETE output of nmap
$output = ob_get_contents(); // capture output buffer contents
ob_end_clean(); // shutdown output buffers
echo $output; // echo it
.
// okay, how about we try a 'proc_open()'?
// nope, this doesn't work either. I just get a value of "command returned -1073741515"
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("file", "errors/errors.txt", "a") // stderr is a file to write to
);
$cwd = 'errors';
$env = array('some_option' => 'aeiou');
$process = proc_open('C:/nmap -V', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process))
{
// $pipes now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
// Any error output will be appended to /errors/errors.txt
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
$return_value = proc_close($process);
echo "command returned $return_value\n";
}
And many others, but I get absolutely NOTHING back from $output. I've done a lot of Google searching too, but I still can't figure it out. Many examples also seem to be for Linux which doesn't help.
Thanks.
Okay, I get an output using this code. I will continue coding and finish the rest of the program. Thanks to 'Chris Haas' for the suggestion in using proc_open
NOTE: The directory that contains the 'errors.txt' file must have 'IIS_IUSRS' write permissions. When in doubt, check your PHP error log.
$descriptorSpec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("file", "errors/errors.txt", "a") // stderr is a file to write to
);
$env = array('bypass_shell' => true);
$process = proc_open("NMAP.EXE -V", $descriptorSpec, $pipes, "C:\\Program Files (x86)\\NMap", $env);
if (is_resource($process))
{
// '$pipes' now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
// it is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
$return_value = proc_close($process);
echo "<br /><br />Command Returned: $return_value\n";
}
Nmap version 7.91 ( https://nmap.org ) Platform:
i686-pc-windows-windows Compiled with: nmap-liblua-5.3.5
openssl-1.1.1h nmap-libssh2-1.9.0 nmap-libz-1.2.11 nmap-libpcre-7.6
Npcap-1.00 nmap-libdnet-1.12 ipv6 Compiled without: Available nsock
engines: iocp poll select
Command Returned: 0
I want to run .exe file from php. It asks for user input one by one. Is there any way I can do this.
I tried using shell_exec(), exec() but they didn't return the expected results.
I found a solution for my own query, please find the piece of code below that solved the purpose:
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "error.txt", "a")
);
$process = proc_open('xyz.exe', $descriptorspec, $pipes);
$input1 = "1";
if (is_resource($process)) {
print fgets($pipes[1]); // this will help you read the lines
fwrite($pipes[0], $input1."\n"); // to provide input
print fgets($pipes[1]);
fclose($pipes[1]);
fclose($pipes[0]);
$return_value = proc_close($process);
echo "command returned $return_value\n";
} else {
echo "Resource unavailable";
}
I have a php file which currently puts in the browser the output of a bash script:
<?php
ob_implicit_flush(true);
ob_end_flush();
$cmd = "./bash_script.sh";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo '<pre>';
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
}
}
echo '</pre>';
?>
However, in CLI the output of my bash_script.sh is colored formatted but in the browser output there is no formatting and colors are not visible.
I have tried the following simple example with command ls --color:
<?php
$cmd = "ls --color";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo '<pre>';
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
}
}
echo '</pre>';
?>
And its output comes with color codes (or at least I believe so), that is:
[01;34mFolder1[0m
[01;34mFolder2[0m
[01;34mFolder3[0m
[01;32mFile1[0m
[01;34mFolder4[0m
However, with my script, those color codes don't appear.
Is it possible to print the same colored output I get in CLI to the browser?
Since there are color formats in the output, you could set a translations table that converts between the cli and php.
A quick-n-dirty example:
Define translations
$colors = ['[01;32m' => '<span style="color:green">', …, '[0m' => '</span>']
Then replace
str_replace(array_keys($colors), array_values($colors))
NOTE: usually color formats are defined in this form \e[32mHello world, where \e is a shortand for ESCAPE char, so see case by case forms of defining a color format.
Tool way: you might also try if this works fine: aha, an Ansi HTML Adapter.
I am running a script from here: https://github.com/PokemonGoF/PokemonGo-Bot
The script outputs all the information to the console, but I want to output it to my browser using PHP.
This is my PHP code:
<?php
// Turn off output buffering
ini_set('output_buffering', 'off');
// Turn off PHP output compression
ini_set('zlib.output_compression', false);
ob_implicit_flush(true);ob_end_flush();
$cmd = 'python pokecli.py';
//$cmd = 'python test.py';
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo "<pre>";
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
flush();
}
}
echo "</pre>";
?>
I am not getting any output and also no errors in my NGINX logs.
I have looked at all of the similar questions and none of the answers worked
In timer.php I have this:
$handle = fopen( 'php://stdout', 'wa' ) ;
$unusedEvTimerObject = new EvTimer(0, 1, function ($watchercallback) use ($handle) { //create & call timer
echo "=>".(Ev::iteration() % 60)."<=";
fwrite( $handle, "Hello World! \n");
} );
Ev::run();
fclose( $handle );
And in child.php I have this:
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "/tmp/error-output.txt", "a")
);
$process = proc_open('php ', $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], "<? include('app/timer.php'); ?>");
fclose($pipes[0]);
$output = "";
while (!feof($pipes[1])) {
$output .= fgets($pipes[1]);
};
fclose($pipes[1]);
$return_value = proc_close($process);
echo "command returned $return_value\n";
}
If I invoke timer.php direct with
$php app/timer.php
the output I get is "=>1<=Hello World! =>2<=Hello World!"
but if I invoke with $php app/child.php
I get no output whereas I'd expect stdout from timer.php to redirect to child.php and be printed by it.
I'm flailing a bit & I'm guessing child.php is not getting any input but I can't see why. HALP!
The $output isn't printed in the sample code.
while (!feof($pipes[1])) {
echo fgets($pipes[1]);
};
Calling $> php child.php then prints the timer output