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);
}
?>
Related
I'am stuck since days while requesting grep on PHP, it work in cli but don't return anything via http.
it search for files that contain non UTF-8 carachters
in CLI it retrun ������ but nothing (array is null) from the web
<?php
exec("/sbin/grep -axv '.*' /srv/http/test 2>&1", $datareturn);
print_r($datareturn);
?>
disable_functions = is empty in php.ini
Also tried with proc_open :
<?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
);
$process = proc_open(
"/sbin/grep -axv '.*' /srv/http/test",
$descriptorspec,
$pipes
);
if (is_resource($process)) {
// Closing $pipes[0] because we don't need it
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
//avoid a deadlock
$return_value = proc_close($process);
echo "command returned $return_value\n";
}
?>
In CLI it return :
"������
command returned 0
From http, "command returned 1", error-output.txt is empty in 2 cases
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 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
I need the file stream.
For example
private function faviconFoundExec($url)
{
exec('wget ' . $url . ' -O ../favicons/test.jpg 2>&1', $output);
}
will save the actual file, but I need the file stream, the same thing that file_get_contents would return as below.
private function faviconFoundGet($url)
{
return #file_get_contents( $url );
}
I'm looking at passthru but the documentation is a bit unclear.
You can get a stream from a command with proc_open
$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
);
$cmd = 'wget -qO- ' . $url;
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
$contents = 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
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).