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
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 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);
}
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'm using PHP exec() in a script to merge PDF files with PDFTK.
From PHP docs: exec function says the second argument, if provided, will list each line from the console output. All I get is an empty array though.
Example of code being used:
exec(pdftk "file1.pdf" "file2.pdf" Merged_File.pdf, $output = array(), $result);
I can successfully get errors if I run the code in the console, but I'd like for my application to have access to the full text errors.
You are probably looking to get messages from stderr using proc_open. Something like this:
<?php
$cmd = "/path/to/script arguments here";
$cwd = dirname(__FILE__);
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w"), // stderr
);
if ( ($process = proc_open($cmd, $descriptorspec, $pipes, $cwd, null)) !== false )
{
// Standard output
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
// Errors
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
proc_close($process);
}
?>
I'm invoking the proc_open() and I can't capture the output of the process written to the stderr:
$curFolder = getcwd();
$procDescriptor = array( 2 => array( "pipe", "w" ) );
$cmd = "MyApp.exe -f optimization.csv";
$process = proc_open( $cmd, $procDescriptor, $pipes, $curFolder );
if( is_resource( $process ) == true )
{
$procStatus = proc_get_status( $process );
while( $procStatus['running'] === true )
{
if( !feof( $pipes[2] ) )
{
$logLine = fgets( $pipes[2] );
echo( "Read >${logLine}<" );
}
sleep( 1 );
}
}
The program hangs on the fgets(). If I run the program from the command line, everything works, i.e. there is something written to the stderr (and I also tried by using the stdout with the same result). I'm running the script on Windows - the same script on Linux runs smoothly.
You have an endless loop.
$procStatus['running'] will never change unless you put the call to proc_get_status() inside the loop. PHP does not have dynamic properties like JavaScript.
I added the line
$procStatus = proc_get_status( $process );
right after the sleep() and it works fine.
From the proc_open() docs:
<?php
$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", "/tmp/error-output.txt", "a") // stderr is a file to write to
);
$cwd = '/tmp';
$env = array('some_option' => 'aeiou');
$process = proc_open('php', $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 /tmp/error-output.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";
}
?>
Perhaps your process doesn't report to stderr if you find it empty
I'd recommend also adding stdin and stdout streams, even if you don't consume the data; some C libraries get into a tizzy if the streams are not there, and can either exit early (glibc) or potentially wedge (some versions of MS libc).