I am trying to spool a file to a printer attached to the server using PHP.
I send a command such as lp -d 'Brother_QL-570' '/Users/user_name/Documents/wwwroot/mmsprint/mmsUw8Vv9 using EXEC in PHP and get a return value of 5. The command works fine in the terminal window.
If I send ls, whoami etc, the command executes fine.
whoami and ls live in /bin, so I created a symbolic link for lp and that made no difference.
Also tried /usr/bin/lp and that did not work either. I'm pulling what little hair I have left out over this.
Safe mode is off. The path variables are the same between PHP and my terminal environment.
I am running MAMP on Lion.
FWIW, the command cat /Users/user_name/Documents/wwwroot/mmsprint/mmswKJqYK | lp -d Brother_QL-570 has a return value of 133.
This is my code:
$temp_file = tempnam("./", 'mms');
$pdf->Output($temp_file, "F");
$pdf->Close();
$cmd = "lp -d 'Brother_QL-570' '".$temp_file."'";
exec($cmd,$output,$retval);
error_log("-----cmd=".$cmd."\n", 3, "printCard.log");
foreach ($output as $a) {
error_log("-----output=".$a."\n", 3, "printCard.log");
}
error_log("-----retval=".$retval."\n", 3, "printCard.log");
Any thoughts? What am I missing? This should be easy. Argh!!
It turns out to be a problem with MAMP. I googled "MAMP exec fails" and came up with several good answers. Its a compatibility problem with libraries. I added DYLD_LIBRARY_PATH='' && to the command and Bob's my uncle. Thanks for the replies.
What is the output from the command?
Most likely the PHP user (apache probably) has no permission to print things. Add that user to the lp group. (Assuming macs work similar to unix in this.)
I found a similar solution to the one mentioned about using DYLD_LIBRARY_PATH='' &&. Using this worked for me, so I tried to find a more permanent fix than including this in all my code. I opened up the file /Applications/MAMP/Library/bin/envvars and commented the following two lines out:
DYLD_LIBRARY_PATH="/Applications/MAMP/Library/lib:$DYLD_LIBRARY_PATH"
export DYLD_LIBRARY_PATH
After restarting apache, this is working GREAT! Not sure why this is happening to me though. Might have to do something with the fact that I am running 2 virtual hosts.
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
I am installing InfiniteWP on a local environment using MAMP. Everything works perfectly except for my inability to figure out how to setup a cronjob properly. I did find some information (dated?).
I found this: http://www.freewaytalk.net/thread/view/114906 . But am a bit worried that I may be implementing something dated.
The instruction given by InfiniteWP in order to start the cronjob say this:"php -q -d safe_mode=Off /Applications/MAMP/htdocs/IWP/cron.php >/dev/null 2>&1" So I need instruction on how to implement this php command on my Mac. Terminal?
I'd really appreciate advice and validation on the best course of action.
You could always use a GUI such as : http://code.google.com/p/cronnix/
This is simply a front end to the crontab tool, then simply set the time you want it to run and the URL to:
/Applications/MAMP/htdocs/IWP/cron.php
I didn't have any luck with that google code option but Mac has cron natively and your InfiniteWP code can be added in a few lines. See instructions here: http://www.maclife.com/article/columns/terminal_101_creating_cron_jobs
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.
I'm currently using the Pygments for PHP plugin that is located here: http://derek.simkowiak.net/pygments-for-php/.
The line that actually calls Pygments from that code is an exec() passed: pygmentize -f html $extra_opts -l $language $temp_name as the command. This all works fine, and I get back the output and it is formatted by the plugin.
What I would like to happen at the same time is for Pygments to create an image of it, so I pass exec() a similar command: pygmentize -f png $extra_opts -l $language -o $full_image_path/$output_file.png $temp_name This is where I run into a problem. The image never shows up in the expected folder.
However, if I var_dump() that command string before I exec() it and take it and run it straight from the command line, it works fine.
I have tried echoing exec('whoami') which tells me that the PHP user is www-data. I've tried giving permissions to www-data and changing ownership to www-data on the folder where I store the images. I've also tried changing permissions to 777 just to see what would happen, and the answer is nothing.
Is there something I'm missing? I'm running out of ideas to try. Thank you!
Edit: Another thing that I've checked is the output from the exec command, and the return value. It outputs an empty array, and it returns 1 as the return value.
Edit 2: After seeing that that directory should be writeable/readable for the PHP user, is it possible that pygments doesn't have permission to write it as a specific user? I'm not sure this makes sense, as when I run it myself it works fine, and in fact, when PHP runs it with the HTML lexer, it is able to run. I'm not very experienced in Python, so I don't know if this is a potential issue.
I guess you cannot do it like this.
$output_file.png
Try
$file = $output_file.".png"
and substitute in the exec
Ended up being an issue with the font that was installed for use by the www-root user. Apparently the one that is used by default for Pygments was installed only for the user that I was running as when I use the command line.
The way I was able to figure this out, was running
exec("$command 2>&1", $out, $code);.
The extra 2>&1 redirects stderr into the output for me to see the issue.
The $out parameter showed the FontNotFound error that pygments was throwing.
I changed the font that Pygments used via the command line using: full,style=manni,cssclass=pygmentize_kbOKBd,font_name='DejaVu Sans Mono' -l php -o /srv/www/path/to/images/uploads/2513732976ad4b7.02729290.png /tmp/pygmentize_kbOKBd after finding which fonts I had available to me.
To see which fonts I had available to me as the user running the script, I just ran fc-list in an exec() command for Ubuntu, and checked the output of that for the list of available fonts.
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 ...'