Is it possible to execute cmd commands in Windows OS with PHP exec() function?
I tried this:
<?php
try {
echo exec(
'O:\test\pdftk.exe O:\test\outputs\OPP\out.pdf O:\test\outputs\OPP\out2.pdf cat output O:\test\123.pdf'
);
} catch (Exception $e) {
echo $e->getMessage();
}
Basically, I'm trying to merge two pdf files with the pdftk program. If I just write the same exact command to the cmd by hand, it works and the O:\test\123.pdf file is created. But when I execute the above PHP file, nothing happens (blank page, the file is not created).
Can your PHP user access cmd.exe? You might find the tools at Microsoft's Sysinternals very useful; particularly the process monitor.
Try escaping the directory separator:
exec("O:\\test\\pdftk.exe O:\\test\\outputs\\OPP\\out.pdf O:\\test\\outputs\\OPP\\out2.pdf cat output O:\\test\\123.pdf");
Or even better, use single quotes instead:
exec('O:\test\pdftk.exe O:\test\outputs\OPP\out.pdf O:\test\outputs\OPP\out2.pdf cat output O:\test\123.pdf');
Here is a project that allows PHP to obtain and interact dynamically with a real cmd terminal. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
//if you prefer Powershell, replace 'cmd' with 'powershell'
$shellObj = \MTS\Factories::getDevices()->getLocalHost()->getShell('cmd');
$strCmd1 = 'O:\\test\\pdftk.exe O:\\test\\outputs\\OPP\\out.pdf O:\\test\\outputs\\OPP\\out2.pdf cat output O:\\test\\123.pdf';
$return1 = $shellObj->exeCmd($strCmd1);
The return will give you the command return OR error from cmd, just as if you sat at the console. Furthermore, you can issue any command you like against the $shellObj, the environment is maintained throughout the life of the PHP script. So instead of bundling commands in a script file, just issue them one by one using the exeCmd() method, that way you can also handle the return and any exceptions.
try Executing using the Admin Privileges for command prompt
Related
I am trying to run some flyway commands inside a function from php.
it's a simple clean function that goes something like this:
function clean_schema() {
chdir('my/current/path');
try{
exec('flyway clean', $output, $result);}
catch(Exception $e){
var_dump($e);
}
}
Now as output and result I get an empty array and the error 127. I've looked around and found that that means that I do not have flyway set as a system environment, but if I run the flyway clean command directly in my cmd shell program, it works just fine.
Error code 127 means the executable was not found in the given context. Your shell differs from one executed from the web context, probably because your PATH environment variable is different.
Have you tried executing the app with an absolute path instead? Learn where the executable is first:
which flyway
then:
exec('/absolute/path/flyway clean', $output, $result);
I have tried to run a batch file using PHP:
$script = "\\\MAFINFWWWPV02\D$\WebContent\\engsys.corp.ftr.com\BatchFiles\CopyFiles.bat";
exec($script,$ReturnArray,$ReturnValue);
//shell_exec($script);
//system('cmd /c $script');
//system($script,$ReturnValue);
None of these work! I've tried
var_dump($ReturnValue); echo "<br>";
var_dump($ReturnArray); echo "<br>";
to try and see what is going on, but I get what appears to be normal output like this:
int(1)
array(0) { }
But the files that I'm trying to copy with my bat file, which works fine when run manually, don't get copied!
Edit additional question
Do the \ need to be escaped in the file address?
EDIT 2
Here's what I get from running icacls:
CopyFiles.bat NT AUTHORITY\IUSR:(I)(RX)
NT AUTHORITY\SYSTEM:(I)(F)
NT AUTHORITY\NETWORK:(I)(RX)
CORP\ibb601:(I)(F)
CORP\taw330:(I)(F)
CORP\mmm976:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX,W)
I have full control and everybody else has at least read/execute.
EDIT 3
I have narrowed it down. It's not that the commands are not working it's that permission is denied to the files. Which I don't understand since everyone has write and read/execute access to the entire folder.
EDIT 4
I am running the commands from above trying to get it to work. I am using a function (var_export(my_exec("shell_exec($script)"));) to print what the errors are to my screen. I keep getting something like this:
'\'shell_exec\' is not recognized as an internal or external command, operable program or batch file.
I get a different one for each shell_exec, system, and exec. It just keeps saying that the command is not recognized. This is being executed on a Windows Server 2012 R2 Standard 64-bit. Is there something that I'm doing wrong with the commands?
Function that I'm using to print errors (I found it on another post):
function my_exec($cmd, $input='')
{
$proc=proc_open($cmd, array(0=>array('pipe', 'r'), 1=>array('pipe', 'w'), 2=>array('pipe', 'w')), $pipes);
fwrite($pipes[0], $input);fclose($pipes[0]);
$stdout=stream_get_contents($pipes[1]);fclose($pipes[1]);
$stderr=stream_get_contents($pipes[2]);fclose($pipes[2]);
$rtn=proc_close($proc);
return array('stdout'=>$stdout,'stderr'=>$stderr,'return'=>$rtn);
}
I finally got it to work. Here's what I ended up with:
$script = chr(92) . chr(92) . 'MAFINFWWWPV02\D$\WebContent\engsys.corp.ftr.com\BatchFiles\CopyFiles.bat';
if (!file_exists($script))
{
var_dump($script); echo " Script<br>";
echo "Script doesn't exist!<br>";
var_dump(!file_exists($script));
}
else
{
system('cmd /c ' . $script); echo " <br>";
}
Sometimes I still get the Script doesn't exist! message, but that is usually when I'm connected to the #1 server and not the #2 server. The .nat looks like this:
echo off
SET source2="\\MAFINFWWWPV02\engsys.corp.ftr.com"
START /wait NET USE L: "\\MAFINFWWWPV01\engsys.corp.ftr.com" Password /user:UserName
xcopy %source2% L: /E /Y /Q
NET USE L: /DELETE
You don't need to escape \ when inside single quotes.
If you want to run a script, make sure is exists and is executable:
$script = '\\MAFINFWWWPV02\engsys.corp.ftr.com\CopyFiles.bat';
if (!file_exists($script) || !is_executable($script)) {
// Im' sorry dave
}
// carry on...
If the script is run through a webserver, make sure the user running the service has execute rights, not your own user! is_executable only checks if the file is an executable, not if the user running the script has executable rights
Since your return code is 1, you probably have some permission issue. A successful execution has return code 0
Also consider the following note from the docs:
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.
To have a OS agnostic method of running exernal processes, have a look at the Symfony Process component
after many hours. you should try
c:\\a\\b\\c
instead of
c:\a\b\c
I have a PHP script that is run via CLI. In turn I want that script to call a bash script, but preferably I would like to break up the BASH requests so I can see the action as it is happening.
I can seem to set Environmental variables and they seem to exist between shell_exec() functions. But even when I have a source file like:
source ./bashes/functions.sh
And in the source file I use "export -f function-name" to export the functions in the script before executing the next line, the next line does not see the functions.
$file = file('./bashes/bash_testing.sh',FILE_SKIP_EMPTY_LINES);
//we want to watch this in realtime so write each line seperately to shell.
foreach($file as $command) {
$output->writeln(shell_exec($command));
}
The function $output->writeln is a helper function just to echo the returned result. But basically the error I get is
sh: now: command not found
now is defined as a function in the included bash_testing.sh shell script.
Anyone know how I can resolve this issue?
Here is the source to the ./bashes/functions.sh file:
function now {
date -u +%T
}
export -fx now
There is a way to maintain a single bash shell, execute commands and handle the return. I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
I would suggest not triggering a bash script but rather trigger the induvidual commands. That way you can handle the return and not have to build exception handling in bash.
After downloading you would simply use the following code:
//get a real bash shell.
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', false);
$return1 = $shell->exeCmd($command1);
//logic to handle the return
$return2 = $shell->exeCmd($command2);
//logic to handle the return
..... etc
Is this possible?
What I want to do is send:
run_app.exe -param 'test' -name 'tester'
to a windows cmd line from PHP.
Is this possible or do I need to write a windows service that is somehow triggered by the application?
You can use exec() for that.
Have you tried exec?
Or you can use:
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run(strCommand, [intWindowStyle], [bWaitOnReturn]);
Here you can find the run method params: http://msdn.microsoft.com/en-us/library/d5fk67ky%28v=vs.85%29.aspx
And here is the COM class doc: http://www.php.net/manual/en/class.com.php
With this method you can do so much more in windows :).
I used it becaus of the [bWaitOnReturn] parameter which I couldn't do using any other method.
Here is a project that allows PHP to obtain and interact dynamically with a real cmd terminal. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
//if you prefer Powershell, replace 'cmd' with 'powershell'
$shellObj = \MTS\Factories::getDevices()->getLocalHost()->getShell('cmd');
$strCmd1 = 'run_app.exe -param "test" -name "tester"';
$return1 = $shellObj->exeCmd($strCmd1);
The return will give you the command return OR error from cmd, just as if you sat at the console. Furthermore, you can issue any command you like against the $shellObj, the environment is maintained throughout the life of the PHP script. So instead of bundling commands in a script file, just issue them one by one using the exeCmd() method, that way you can also handle the return and any exceptions.
I'm attempting to get PHP to call a batch file which will take an RTF file and convert it to a PDF using an OpenOffice macro. I've tested the batch file on the command line and it works fine, but I'm not having any luck calling and using the same batch file from PHP.
My machine OS is XP professional SP 3. I'm running IIS 6 and PHP version 5.2.9.
I've granted execute permissions to the internet user on c:\windows\system32\cmd.exe.
I specified the full path to the batch file being executed and the full path to the RTF file to be converted.
The PHP looks like this where $arg is the RTF to be converted:
$arg = "C:\\web_root\\whatever\\tempOutput.rtf";
$command = "c:\\windows\\system32\\cmd.exe /c c:\\web_root\\whatever\\convert.bat $arg";
Then inside a try-catch I call the exec command:
exec("$command 2>&1 && exit", $ret, $err);
I echo the results after the catch:
echo "ret: ";
print_r ($ret);
print "<br>";
echo "err is ";
echo $err;
print "<br>";
echo "DONE!";
And this is what I see:
ret: Array ( )
err is 0
DONE!
The RTF file does not get converted and I'm not seeing the errors. Any ideas on what I can try next? Thanks!!!
I'm going to bet this is about permissions.
In a typical setup, PHP runs as apache - so you'll want to make sure apache has the rights to execute the batch file.
also, check this relevant SO question, and this google search.
Looks like the output array is empty. Is your batch script supposed to have output?
Also, escapeshellcmd and escapeshellarg should be used
Are you using IIS as your webserver? If so, the PHP exec function will not work by default and you should NOT circumvent the security measures that prevent it from running.
Check your event viewer and you should find some errors pertaining to your problem. Run a query through google for: IIS PHP exec. This should give you a large selection of information about the problem.
Basically, the PHP exec function tries to fork a new cmd.exe instance. IIS prohibits this because it could open a security hole in the system.
The best solution that I have come up with is to have your php script either write the command that you want to execute to a flat file or make a database entry. You will then need to write a seperate script that is launched by the windows scheduler to run every 10 minutes or so that will check your flat file or database for commands to run. The new script will then run the commands and then place either the results or an execution confirmation that your web app will be able to access at a later time.
It's a kludge for sure.
Is PHP running in safe-mode? If so, shell commands are escaped with escapeshellcmd. Perhaps this is the problem?
Do you have control of the server running the PHP script?