I have a development / testing setup on a windows box and need to test calling a background process. I am using http://www.somacon.com/p395.php as a list of options for running a background service.
Here is the sample code I am trying to run:
$string = "PsExec.exe -d cmd /c \"mspaint\"";
echo $string;
exec($string, $data);
This works when I type it into the command line.
I haven't attempted to do a lot of exec's on Windows, but it would be nice to be able to test it locally before moving to a Linux box.
Right now, I am thinking it has something to do with the fact that psexec opens a new window? I don't know how to fix that, however.
There are no apache or PHP error logs being generated, the page just never stops. This also seems to override PHP's max execution time.
EDIT:
This is not fully correct answer. The command psexec \\machine cmd.exe /C 1 & dir won't hang because psexec first return saying that command 1 doesn't exists in remote machine and then dir is evaluated in the local machine. I got tricked by cmd operator order. The & operator is being invoked in the local cmd.exe process, not the remote one. But the logic still applies if you quote the command: psexec \\machine cmd.exe /C "1 & dir".
Original Answer:
There is something strange going on while invoking psexec within PHP in windows. No matter if you are using shell_exec(), exec(), popen() or proc_open(). It will hang anyway.
Honestly I don't know what's going on, you could also download PsExplorer in order to trace your process command line, arguments, etc. You'll find this tool very useful.
I'm using XAMPP on Windows, and after certain tests I found this:
First of all create a test file (i.e. test.php) and place it in your web server so you can access it with this content:
<?php
echo "<pre>".shell_exec("psexec \\\\machine <options> cmd.exe /C dir")."</pre>";
?>
Note that you could use GET arguments in order to create a more flexible example. To debunk that this indeed is working before you test over a webpage, issue the command php <path-to-the-file>\test.php. That will work perfectly. But, it won't work on a web browser.
If you kill the process, you'll get the first line: El volumen de la unidad C no tiene etiqueta.. Next line, in my language there's an accent included so I thought It could be encoding (or code pages) issues. So instead of cmd.exe /C dir I tested cmd.exe /C chcp 850 && dir. That, for my surprise, works.
Then, I realize that no matter what command you set before it will also work, for instance, cmd.exe /C 123 & dir (note the single & as I'm not evaluating the command output).
Honestly, I don't know what is going on with psexec and PHP via web browser. More surprisingly, commands like cmd.exe /C copy cmd.exe cmd.exe.deleteme and cmd.exe /C mkdir deletethis will work!
So, you could give it a try to cmd.exe /C 1 & \"mspaint\" as your problem and my seems similars. For single commands could be a workaround but I'm developing an unattended framework for installing software and all my files are .cmd or .exe or .bat files.
Let me know If you found something interesting :)
I have a solution!
This topic is old but still relevant. I wanted to use PsExec 2.2 with PHP 7.2.0 RC3 to execute a script remotely. I need the output of the script and so i was using PsExec.exe -accepteula \\HOST -u xxx -p xxx with >> LOGFILE 2>&1.
Because I dont want to wait the script to finish, I used exec() like this: exec('start /p cmd /c PsExec.exe -accepteula \\HOST -u xxx -p xxx >> LOGFILE 2>&1').
My php script continues working and PsExec does his job too.
Everything works fine but my LOGFILE always contains only the first line of the STDOUT output.
I have tried many solutions mentioned here, but none of them worked for me. Executing the command in the CMD directly, PsExec returns all lines of STDOUT but inside php it does not.
At the php doc for exec() I have found comments where some people used PsExec to run a programm without waiting (http://php.net/manual/de/function.exec.php#86438). As a last chance I tried the following: exec('PsExec.exe -accepteula -i -d cmd /c PsExec.exe -accepteula \\HOST -u xxx -p xxx >> LOGFILE 2>&1')... And it works!
PsExec now returns everthing into my LOGFILE. I hope I could help you and save you some time.
My current solution was to use WScript.Shell:
$string = "cmd /c \"cd {$full_base}{$newSource} && ant release > compile.txt\"";
$Shell = new COM("WScript.Shell");
$exec = $Shell->Run($string, 0, false);
Not sure if this was definitively answered or not, but I was having the same problem with PSEXEC hanging, though in my case, on some machines it did, and others it didn't. It turned out to be accepting the EULA. On machines that I'd run it from a command line and used the same username/password as my PHP script, it ran without hanging.
Further research showed that I could specify the EULA acceptance by including it in the command being executed from PHP:
This DID hang: psexec \\MACHINENAME ...
This did NOT: psexec /accepteula \\MACHINENAME ...
ok here are the things. I also jumped into similar condition as you were and hopefully since i am commenting this late you must have figured out a way too .But for those who are still in this problem , i suggest them few tips .
1)The code that has been posted is super fine , no problem with that thing. If your page hangs out infinitely then try to add -i -d params before the source exe. (see the documentation HERE ). You can also add -accepteula (EULA) flag in the command to let the page load and not to wait for that command to finish(solves the infinite wait problem).
2)For me these things didnt work . It doesnt mean that you guys dont try these things .these are the first steps if your code starts working then thats fine for you.Else ,make another account as an adminstrative one ,type services.msc in the start menu , you will see the page there. Search for wampapache or xammp services ,excluding mysqld one. Then simply click on that service .GO to log on tab ,select This account .Select the previously made admin acc , type its password if you set that else leave the textbox empty.Type the name of that account as \\accname at the name field . If u dont know the account name ,Click to Browse->Advanced->FInd now you will see that name account . Select, apply settings and restart the wamp app and you are good to go :)
Also make sure to double check the string you feed into your exec command. Seems trivial, but had me stumped for awhile. In many cases PHP escapes the double backslash in your machine address which throws everything off. To get around this, create your string like:
$string = 'PSExec /accepteula \\\\MACHINENAME ...'
Related
I am having issues executing a VBScript through Apache (WAMP) on Windows Server 2012. I am attempting to convert a Docx to PDF, and the script runs perfectly from the command line, but fails when running through PHP. Rather than posting the vbscript, I will provide a link to it: http://bit.ly/1gngYAn
When executed through PHP as follows, WINWORD.exe starts, as does the VBScript, and it hangs there and nothing happens. No PDF is generated (and I never see the ~temporary.docx hidden file pop in the directory).
I have tried just about every iteration of exec, system, passthru and COM ( 'WScript.Shell' ), and all have the same outcome.
To avoid "escaping" issues, I also tried executing the script though a .bat file so no arguments needed to be passed, and the outcome was the same.
Here is my current php code (convert.vbs is the code from the link above):
$obj = new COM ( 'WScript.Shell' );
$obj->Run ( 'cmd /C wscript.exe //B C:\Users\Administrator\Desktop\convert.vbs c:\wamp\www\fileconv\temp_store\52fa8272bf84f.docx', 1, false );
//I have tried different "window styles" too, and it doesn't make a difference
I also tried modifying the apache service user to run as administrator (this is not a production server), and enabled "Allow service to interact with the desktop", and it had the same outcome.
I have also made sure the directories had "full control" by everyone (reading, writing, executing, etc).
It runs perfectly if I run from the command line or with my ".bat" file.
Since it hangs (the script and word, not apache), I have looked at the event viewer in the control panel, but there are no events that pertain.
My questions is firstly, why is this happening, and secondly, if the first cannot be answered, is there a way that I can get a more in depth look at what is happening when the process is executed, as to further troubleshoot it? As of now, I have no data to review or output to see to help me troubleshoot.
Please feel free to ask for any details. I have tried many, many iterations to try to get this to work, searched high and low, and can't seem to come up with any answers.
I appreciate your assistance,
Louis
It took me a couple of days, but here is the solution I found:
I used PsExec - http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx
The following flags are required: -h -i -accepteula -u -p
(I tried without the -h, -accepteula and -i, but no dice. This is running on Windows Server 2012 under WAMP)
Here is an example:
exec('c:\psexec\PsExec -h -i -accepteula -u Administrator -p '.$password.' C:\Windows\System32\CScript.exe //Nologo //B c:\wamp\www\fileconv\convert.vbs '.$filename)
Now it executes properly and as intended.
I hope this helps someone in the same situation!
PS The WScript.Shell method of execution I used in my question works just as well as exec(), except exec() waits until the process exits.
You should use exec() function
this is the url http://php.net/manual/fr/function.exec.php
One of my lines of shell command is not executing despite other similar lines working. I am running on a linux machine using a Ubuntu 12.04 based OS. I have tried using exec as well, still doesn't work.
I actually had this working at some point, where I ran into the hanging issue (waiting for command output), which is why I'm redirecting output to /dev/null. So some where in the development something changed. We did create a debian package to install with and I had run that install package so I thought maybe in overwriting a file the permissions got changed so I added read/write/execute to all users/groups/owners but that didn't work either.
The code is here:
if(isset($_POST['activateXML']))
{
if (videoConsistencyCheck())
{
`cp {$fileXML} /apps/video/xml.xml`;
`sudo /apps/video/vsss restart >/dev/null 2>&1 &`;
systemUnvalidate();
header('Location: index.php?app='.$_GET['app']);
die();
}
}
I know that the first line in the if statement gets executed. The line of code works fine in the actually terminal, so that isn't the problem either. I did lots of Googling and all I could find is an unanswered question, any advice would be helpful.
EDIT: so what appeared to be not working was in fact calling the command as intended but in the bash script I was calling the start-stop daemon was not working
EDIT 2: I made a test php file and ran the code from the terminal, fixed the start-stop-daemon error by adding sudo to the commands but it still doesn't work in my code. I am calling this code when a submit button is pressed.
use additional parameters, especially output:
exec($command,$output);
var_dump($output);
to determine what can be wrong with your command. If it doesn't work, please show us your code where you use your exec's.
The issue lay with a call to a binary file in the vsss script that could only be run as root. We did not want to allow access to that binary file to just anyone. The solution we came up with involves calling chmod +s on the vsss script which allows permissions for user and group IDs but keeps its owner permissions. We then added the PHP user, which was www-data, to the sudoers file using the NOPASSWD parameter. In my PHP code I then used the line:
exec('sudo /apps/video/vsss restart >/dev/null 2>&1 &')
The shell_exec()/backticks would not work with this method.
purpose: use php to input commands directly into the minecraft server console
Im trying to use a php script (run from browser) to exec() a shell script. when i run the php from a terminal it works! But in the browser, nothing happens.
exec('sudo -u root sh /home/minecraft/whitelist-reload.sh', $out, $ret_val);
When running from terminal, i get a "array 0" but the browser gives me a "array 1"
what is the issue?
and once i run the shell, shouldn't everything after that work as if you were on a terminal?(does it matter what is inside of shell script?)
the shell has all rx permissions and is in the sudoers file as
www-data ALL = NOPASSWD: /home/minecraft/whitelist-reload.sh
The problem is, that you run the script on a terminal as a user that probably has the sudo rights, whereas the apache/webserver user doesn't, so the $ret_val (which is actually just a status code) is set to 1 (means error).
try var_dump($out); in both cases to see the results of your exec call. To do this kind of thing from the browser, you might want to look into proc_open and family, or have a script that is chmod'ed to 777, so the apache user can run it, too. Let that script then call the actual shell script and return it's output back. This is, however very dangerous, and should only be used for testing environments on your own machine. Never do this in production environments!
I have posted a couple of questions here, too that might prove informative:
interaction over ssh
opening a second shell, and load profile variables AND call another script
Turns out... after inputting www-data into the sudoers file, all i needed to do was take of the "-u root" after it
I'm building a PHP web application that will run on my machine, and one of its purposes is to call HandBrakeCLI with an exec() or similar call. If I run the command
HandBrakeCLI -i path_to_dvd_drive -o output_file --preset preset_name
from a shell, it works fine. However, when I put the exact same command in an exec() php function (or similar), it doesn't work, and doesn't return anything, aside from a return status of 0. No errors, nothing else.
Is this just a simple permissions issue that I'm not seeing, due to the lack of errors being spit out? Or am I missing something else?
For debugging, try running the command from the console but as the user PHP runs as. Here are some pointers how to find out which user that is.
Then use sudo to run the command as the Apache user. You will probably get more helpful information from that.
try to exec your script using absolute path (type which HandBrakeCLI in terminal to find it) and append 2>&1 to the end of command, like:
exec('HandBrakeCLI -i path_to_dvd_drive -o output_file --preset preset_name 2>&1')
this way if command outputs anything to stderr you will see it.
is handbrake in the path of whatever shell PHP is invoking when it does the exec()? Does whatever account PHP/webserver is running under have access to the directory where handbrak.exe is, and have permission to execute handbrake.exe? Does the webserver account have permissions to access the dvd drive, etc...
Many things to check, and without better diagnostic information, this is about the best you'll be able to get here.
I am attempting to create a php script that can connect thru ssh to my Qnap TS219 server and run a command on it.
My script so far connects fine to the server but when I run the command I get an error message and I can't figure it out.
exec.sh
#!/bin/bash
cp /share/MD0_DATA/Qdownload/rapidshare/admin/script.txt /share/MD0_DATA/Qdownload/rapidshare/admin/script.sh
chmod 755 /share/MD0_DATA/Qdownload/rapidshare/admin/script.sh
nohup sh /share/MD0_DATA/Qdownload/rapidshare/admin/script.sh &
exit 0
script.sh
#!/bin/bash
/opt/bin/plowdown -o /share/MD0_DATA/Qdownload/rapidshare /share/MD0_DATA/Qdownload/rapidshare/admin/down.txt 2>/share/MD0_DATA/Qdownload/rapidshare/admin/output.txt
the command that I am currently running thru ssh after I submit the form:
echo $ssh->exec('sh /share/MD0_DATA/Qdownload/rapidshare/admin/exec.sh');
Right now generates the code below but only after I kill 2 bash processes (the page keeps loading indefinetly and the processor activity is at 100% if I don't kill the 2 bash processes):
/share/MD0_DATA/.qpkg/Optware/share/plowshare/lib.sh: line 261: getopt: command not found start download (rapidshare): http://rapidshare.com/files/312885386/Free_Stuff-Your_Internet_eBay_Business_Free_Startup_Resources.rar /share/MD0_DATA/.qpkg/Optware/share/plowshare/lib.sh: line 261: getopt: command not found /share/MD0_DATA/.qpkg/Optware/share/plowshare/lib.sh: line 46: --insecure: command not found Error: failed inside rapidshare_download()
This script will be used in my local network, no access from outside, so I am not worry about security, I know the code looks very basic, primitive but I have no experience with php, shell script, so if someone can make any sense on this and help me out will be greatly appreciated.
Edit1. I also tried the shell_exec command still no joy and if I run the script thru putty works beautifully.
Edit2. I think we are on to something.
I added the code you suggested and I got the following message.
sh: /share/MD0_DATA/.qpkg/Optware/share/plowshare: is a directory /usr/bin:/bin:/usr/sbin:/sbin
I think at the moment the PATH is usr/bin:/bin:usr/sbin:/sbin and I think it should be /opt/bin /opt/sbin because there are the "executables". Any ideeas?
Thanks,
Chris.
Run this
echo $ssh->exec('pwd');
Does it list your path correctly? If so then your problem is NOT PHP, if it doesn't list or still gives an error then PHP is your problem and we can continue from there.
From the error you've listed, my first guess would be that PATH isn't set, so lib.sh can't find what it's looking for.
Remember you're logging in with a custom shell (PHP ssh), quite often things aren't set as they should be, so your scripts might not find requirements like paths and variables.
Edit:
Since it's giving /root, we at least know it's going through, why not also set the PATH etc...
echo $ssh->exec('PATH=$PATH;/share/MD0_DATA/.qpkg/Optware/share/plowshare; sh /share/MD0_DATA/Qdownload/rapidshare/admin/exec.sh');
Remember you can also use this to see what is and isn't being set.
echo $ssh->exec('ECHO $PATH');
I think I got it:
Following viper_sb logic, I changed the code to:
echo $ssh->exec('PATH=$PATH:/share/MD0_DATA/.qpkg/Optware/bin; sh /share/MD0_DATA/Qdownload/rapidshare/admin/exec.sh');
echo $ssh->exec('echo $PATH');
and magic, it worked ... I'll test it further, when I get home, but I think it worked, a file was downloaded in the /Qdownload/rapidshare folder ... hooray.