PHP exec operator doesn't execute specific command - 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.

Related

Running shell script from webserver

I have a shell script named brew.sh as follows:
#!/bin/bash
brew doctor > test.txt
Which works fine when I run it from the command line. It outputs as expected the output of brew doctor to the test.txt file. However, when I call it from a php webpage as below it creates the test.txt file but the file is empty.
<?php
$output = shell_exec("./brew.sh");
echo $output;
?>
I suspected it was a permissions/ownership issue so I used chown to change ownership from username:staff to _www:_www on the parent directory,where it would then create the test.txt file but not write the output to it. I've even tried changing permissions to 777 temporarily on the test.txt and even that didn't work. Ultimately I would like to view the output of brew doctor and brew update on a webpage on my local development machine. Surely it shouldn't be that difficult?
Elias is going to be right I suspect - your environment on the cmd line is not going to be like the environment the script finds itself in within the webserver, assuming the webserver user is even allowed to run a proper shell...
You'll need a path. Check what your path value is, and put it in.
Also doesn't hurt to always include the full path for your binary, i.e. brew.
#!/bin/bash
PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin"
/usr/local/bin/brew doctor > /var/www/whatever/test.txt
.... personally.. This isn't the approach I would use. If this is for brew doctor and brew update I would just use cron jobs that redirect output to a file on the webserver since I wouldn't want the webserver invoking brew commands... someone could DoS the server pretty easily just by requesting those pages a lot. The cron solution is pretty bulletproof though - and in any case with cron I can run it as a more appropriate user where the permissions/environment for brew are likely to work more correctly in any case.
Also - the other guys point about checking errors is a good one. stderr is probably ending up in your web logs at the moment when you get empty output. 2>&1 can make it go into that file instead, probably.
[ Note that it has to be 2>&1 !! I think chris had a typo when he wrote >2&1 which does something very different. 2 is the stderr filehandle which we want to redirect to 1. >2 will redirect 1 (stdout) to a file called 2.
If you add 2>&1 to your shell command, you should get STDERR and STDOUT returned which will at least help you determine what is going on:
<?php
$output = shell_exec("./brew.sh >2&1");
echo $output;
?>

PHP exec() with Pygments for PHP

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.

Executing commands in php as root user in arch linux

i am using arch linux. i want to execute the php file which changes the ip of the system. i did
ifconfig eth0 192.168.163.137
in the terminal and it works fine. the same i tried doing with
shell_exec('ifconfig eth0 192.168.163.137');
in a php file and tried opening the page from a remotely located web browser from another pc connected via router. teh page displays nothing and the code also doesnt execute. i guess its the problem with the user executing it.apache is executing it. so i want it to be run by the root.can anyone please guide me to the execution of my code. i even installed sudo and just put
shell_exec('sudo ifconfig......');
it too doesnt execute...please help...thanku..:)
Sudo normally requires an interactive shell to enter your password. That's obviously not going to happen in a PHP script. If you're sure you know what you're doing and you've got your security issues covered, try allowing the Apache user to run sudo without a password, but only for certain commands.
For example, adding the following line in your sudoers file will allow Apache to run sudo without a password, only for the ifconfig command.
apache ALL=NOPASSWD: /sbin/ifconfig
Adjust the path and add any arguments to suit your needs.
Caution:
There might still be complications due to the way PHP calls shell commands.
Remember that it's very risky to allow the web server to run commands as root!
Probably a better alternative:
Write a shell script with the suid bit to make it run as root no matter who calls it.
shell_exec
This function is disabled when PHP is running in safe mode.
Documentation : http://php.net/manual/en/function.shell-exec.php
So, maybe try tweaking your php.ini file?
Write the commands to a queue and have cron pick them up, validate them (only allow known good requests), and run them, then mark that queue complete with the date and result.
Your end-user can then click/wait for update using ajax.

Can I rip DVDs from a local web app with HandBrake?

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.

run shell script from php

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.

Categories