Passing Params from PHP to Powershell exec - php

I am attempting to write a PHP script that will allow for me to select a few files to download from a predetermined location. I'd like my script to pass an array to a Powershell script that id written earlier and have my Powershell script handle the downloading (basically the php file just needs to tell the powershell file what needs to be downloaded).
I've looked at a few options, and it seems that exec is the command I should use for this (as I do not care about command line output I shouldnt need shell_exec).
So far I've turned OFF safe mode to allow me to use this command. I should also note that the php file will be run from a server, however the powershell files are located on a local machine.
A snippet of the code so far to handle the param passing looks like this:
if(isset($_POST['formSubmit']))
{
$choosePlugin = $_POST['wpPlugin'];
$chooseTheme = $_POST['wpTheme'];
if(isset($_POST['wpTheme']))
{
echo("<p>You selected: $chooseTheme</p>\n");
exec('powershell.exe C:\Wordpress Setup\setupThemes.ps1 $chooseTheme');
}
else
{
echo("<p>You did not select a theme</p>\n");
}
I am a bit confused as to what I should put inside the exec. When I run the above code there are no errors however nothing happens. I am a bit new to this so I apologize if more information is required. Any help is appreciated thank you.

Try to do:
echo exec('powershell.exe C:\\Wordpress Setup\\setupThemes.ps1 $chooseTheme');
to see the results of powershell.exe (remember the double \), also make sure to put the absolute path to the exe file:
echo exec('c:\\PATH_TO_POWERSHELL.EXE\\powershell.exe C:\\Wordpress Setup\\setupThemes.ps1 $chooseTheme');

If you want to pass the contents of the variable you should use double quotes to actually expand it, I guess. Furthermore you should quote the script name because the path contains spaces:
exec("powershell.exe \"C:\Wordpress Setup\setupThemes.ps1\" $chooseTheme");

Related

PHP website not running exec function when passing image as an argument

I'm having trouble running the "exec" function in my PHP website. I am able to run it several times with an executable that just takes in a variable argument and returns some test message. However, when I use an executable that does some image processing, where I want to pass an image from the website that a user uploads as an argument, it does not seem to be executing the executable at all. I even have some cout commands in the executable to ensure its running, but these are not being displayed on the website. So I think that for some reason the php cannot run the executable? I am able to run it fine from my desktop...
Here's an example of the code that isn't working on my PHP website:
$imgtest1="/uploaded_files/me.jpg";
$imgtest2="/uploaded_files/clusteroutput.jpg";
$nosuppix = 400;
$noweight = 100;
$executabletest = exec("ImgProc $imgtest1 $nosuppix $noweight $imgtest2");
echo $executabletest;
Is there a way to debug or get an error output from the exec function? Is there something I'm missing when passing an image to the executable? The executable uses several DLL files which are in the same folder as the executable. Do they need to be packaged together for some reason? I apologize, but I really don't know what's left to test...
***Edit: I'm now able to get it to run if I write out all the code in the escapeshellcmd itself... how come I'm not able to just pass the variables?
$cmdinput = escapeshellcmd('SuperpixelsFinal "D:/WebPages/TALIA ART/TALIA ART/uploaded_files/me.jpg" 400 100 "D:/WebPages/TALIA ART/TALIA ART/uploaded_files/clusteroutput.jpg"');
For anyone else having this issue, it is because I was using escapeshellcmd when I should have used escapeshellarg for each individual string and then run the exec with double quotes using only variables like so:
$executabletest = exec("SuperpixelsFinal $imgtest1 $nosuppix $noweight $imgtest2");

Calling Perl script with PHP, passing variables and put result into a file

I am near losing my mind cause of a perl script I want to call via PHP.
I have a PHP Form where I put in a MySQL Query which gets stored in a file and choosing some variables.
If I call any SHELL command like "top" ... everything works fine, but as soon as I try to call my perl script with variables, there are no results at all.
The file where the results should get stored stays empty.
That's the calling part from the PHP File:
if (isset($_POST['submit'])) {
$file = 'query.sql';
$query = $_POST['query'];
file_put_contents($file, $query);
$command = "perl /home/www/host/html/cgi/remote-board-exec.pl -sqlfileexec query.sql > /home/www/host/html/cgi/passthrutest.txt";
exec($command, &$ausgabe, $return_var);
There is no error message and i already tried debug things, but nothing helped :(
Are you sure that perl is being executed? Perhaps you ought to replace the command with 'which perl' just to make sure, and to use the full path to Perl. Another idea is to make sure your:
perl script is executable (use chmod)
ensure it has '#!/usr/bin/perl' (or wherever your path to perl is)
change the command to "/home/www/host/cgi/remote-board-exec.pl..." without the perl command
dump the contents of your output array ($ausgabe) as if the command fails to execute you may find out what is happening.

make a PHP script executable from CLI and include-able?

Consider this:
#!/usr/bin/php
<?php
class Foo {
static function bar () {
echo "Foo->bar\n";
}
}
if (PHP_SAPI === 'cli') {
Foo::bar();
}
?>
I can execute this from CLI, but when I include it in, say, a CGI-run PHP script, the shebang ends up in the output.
I like simple scripts compact: I guess I could put the class part in a separate "lib"-file and have a simple wrapper for CLI use. BUT I'd like to keep it all in one place without having to worry about include paths etc.
Is this possible without ob_*-wrapping the include to capture the shebang (if this is even possible), or is it dumb to cram all of this into one file anyway? Alternatives/Thoughts/Best Practices welcome!
Edit: I'd like to put the script in my PATH, so calling I'd rather not call it by php file.php. See my comment to #misplacedme's answer
It's actually easy.
Remove the shebang and when you run the script, run it as
php scriptname.php OR /path/to/php scriptname.php
instead of
./scriptname.php
Running php script.php will look in only the current directory, or any directory within PATH. If you absolutely have to run it that way, add it. export PATH=$PATH:/path/to/php/script/folder(in bash)
That will mess up includes unless you're using full paths within the script.
No matter what you do, you'll have to use full paths somewhere.
I'm rather late to this one, but if anyone still cares, you can solve this on Linux by registering a binfmt handler.
As a one-off (resets after reboot):
echo ":PHP:M::<?php::/usr/bin/php:" > /proc/sys/fs/binfmt_misc/register
With this in place, any file that starts with the "magic" string "<?php" will be executed by running it with /usr/bin/php.
You can make this registration permanent by saving the line a file in /etc/binfmt.d
You can remove the registration with:
echo -1 > /proc/sys/fs/binfmt_misc/PHP

Calling php from php through exec() gives no result

I have a PHP script that creates other PHP files based on user input. Basically, there are files containing language specific constants (define) that can be translated by the user. In order to avoid runtime errors, I want to test newly written files for parse errors (due to "unusual" character sequences). I have read several posts here on SO (like PHP include files with parse errors) and tried a function that uses
$output = exec("php -l $filename");
to determine whether a file parses correctly. This works perfectly on my local machine, but at on the provider's machine, the output of calls to exec("php ...") seems to be always empty. I tried a call to ls and it gives me output, leading me to the assumption that PHP is somehow configured to not react to command line invocations or so. Does anyone know a way around this?
EDIT: I forgot to mention, I had already tried shell_exec and it gives no result, either. In response to sganesh's answer: I had tried that too, sorry I forgot to mention. However, the output (second argument) will always be an empty array, and the return value will always be 127, no matter if the PHP file to test has syntax errors or not.
I had the same problem. The solution that worked for me was found in running-at-from-php-gives-no-output. I needed to add output redirection.
$output = exec("php -l $filename 2>&1");
You can try with exec second and third arguments.
second argument will have the output of the command.
third argument will have the return value.
And exec will return only last line of the command.
$filename = "a.php";
$output = exec("php -l $filename",$op,$ret_val);
print $output."\n";
print $ret_val."\n";
var_dump($op);
By executing shell_exec(), you can see the output as if you executed that file via command line. You can just see if there is an error right here.
<?php
if (strpos(shell_exec('php -l file.php'), 'Syntax Error')) {
die('An error!');
}
There may also be a possibility that shell_exec() or exec() may be disable by your host.
Nice idea to check the file validity :-)!
Now, from the PHP manual for exec():
Note: When safe mode is enabled, you can only execute files within the safe_mode_exec_dir. For practical reasons, it is currently not allowed to have components in the path to the executable.
Can you check if this is not the case for you?
Also, can you check by providing the full path of the PHP interpreter in the exec() instead of only php. Let me know how you fare.
Pinaki
the correct way is to add >2&1 as tested on a windows system using imagemagick!
I worked around my original problem by using a different method. Here is what I do now:
Write a temporary file with contents <?php include "< File to test >"; echo "OK"; ?>
Generate the correct URL for the temporary file
Perform HTTP request with this URL
Check if result equals "OK". If yes, the file to test parses without errors.
Delete temporary file
Maybe this could be done without the temporary file by issuing an HTTP request to the file to test directly. However, if there is a parse error and errors are suppressed, the output will be empty and not discernible from the output in the case of a file that gives no parse errors. This method is risky because the file is actually executed instead of just checked. In my case, there is only a limited number of users who have access to this functionality in the first place. Still, I'm naturally not entirely happy with it.
Why the exec() approach did not work, I still do not know exactly. pinaki might be right by suggesting to provide the full path to the PHP executable, but I cannot find out the full path.
Thank you everyone for answering, I upvoted you all. However, I cannot accept any of your answers as none of your suggestions really solved my problem.

How to do command line from PHP script

I need to write a script that will give users info on a given Unix account (the same Unix server that the script lives on). Mostly thing kinds of things that are in the passwd file or available via finger.
PHP is in safe-mode, so I can't access the passwd file via something built into php like file_get_contents(). Also, because it's in safe mode, various other command-line functions are disabled.
I thought I could get the info via a socket (no clue yet what that means, but I thought I'd try) but I get a fatal error that socket_create() is an unknown function. I pulled up the php-config file (which I can't change, FYI), and sure enough, sockets are not enabled.
However, while I was in there, I saw the line '--with-exec-dir=' with no actual directory set.
So then I remembered that when I was trying EVERY command line function, that some threw "not allowed in safe-mode" type errors, while others did nothing at all. If I put something like:
echo "[[";
exec("finger user");
echo "]]";
I'd end up with [[]]. So no errors, just no results either.
Bottom line:
Is there something I haven't tried? (in general)
Is there a runtime config option I can set to make exec() work?
quick note: I tried passthru() as well, specifically passthru("pwd") with still no output.
update
based on feedback, I tried both of the following:
$stuff = exec("pwd", $return);
echo "stuff=".$stuff."\n";
echo "return=";
print_r($return);
which results in:
stuff=
return=Array
(
)
and
$stuff = passthru("pwd", $return);
echo "stuff=".$stuff."\n";
echo "return=";
print_r($return);
which results in:
stuff=
return=1
The 1 sounds hopeful, but not what I want yet.
Idea
So this is actually an update of an already existing script that (please don't ask) I don't have access to. It's a perl script that's called via cgi. Is there a way to do php via cgi (so I don't have to deal with perl or rely on the older code)?
I'm afraid you can't do that in safe-mode. You have to remove the safe-mode if you have control of the server configuration.
I think you can't rely on sockets to read local files, sockets are used for network related things.
exec doesn't inherently return any data.
Try something like,
exec("finger user",$output);
echo "[[";
foreach($output as $key => $value){
echo $value;
}
echo "]]";
Exec returns a value, so do:
$var = exec("finger user");
and then parse the output to get what you want. You can get return status by adding in an optional variable thus:
exec("finger user", $var, $return_status);
or just:
echo exec("finger user");
if all you want is to see the output.
Thanks to all that responded, the following is what finally worked:
Create a cgi-bin folder
Add the following to the top of the php script:
#!/usr/local/bin/php-cgi
I don't know if this is something special on my server configuration, but I can run exec() and get what I'm after.

Categories