I am using red hat enterprise edition n try making a simple php page..
When I try with ...
// html code
<?php
echo exec(<cmd>);
?>
// rest html code
Its working fine
but when tried with ...
// html code
<?php
exec(<cmd>);
?>
// rest html code
Its not working
even a simple command like cat,ls,etc not working and also I tried 2 > &1 then no error is printed .
What could be the possible error ???
Docs:
http://php.net/manual/en/function.exec.php
return a response from the command, you would need to print the response out as well
Example:
<?php
$response = array();
exec('whoami', $response);
print_r($response,true);
?>
okkkkkkk ......... I solved the problem. Actually there were two issues ...
The apache user searches its command in /usr/bin folder by default and the command I was trying to use was located in /usr/local/bin. So I need to create a soft link of that command in the /usr/bin directory.
Secondly , apache is a less privilaged user than root so need to on the sticky bit of command so that apache could successfully run the command.
I hope this will help someone else also who will face the same problem in future.
Related
I have a server running on Linux that execute commands to 12 nodes (12 computers with Linux running in them). I recently downloaded PHP on the server to create web pages that can execute commands by opening a specific PHP file.
I used exec(), passthru(), shell_​exec(), and system(). system() is the only one that returns a part of my code. I would like PHP to act like open termainal command in linux and I cannot figure out how to do it!
Here is an example of what is happening now (Linux directly vs PHP):
When using linux open terminal command directly:
user#wizard:/home/hyperwall/Desktop> /usr/local/bin/chbg -mt
I get an output:
The following settings will be used:
option = mtsu COLOR = IMAGE = imagehereyouknow!
NODES = LOCAL
and additional code to send it to 12 nodes.
Now with PHP:
switch($_REQUEST['do'])
{ case 'test':
echo system('/usr/local/bin/chbg -mt');
break;
}
Output:
The following settings will be used:
option = mtsu COLOR = IMAGE = imagehereyouknow!
NODES = LOCAL
And stops! Anyone has an explanation of what is happening? And how to fix it? Only system displays part of the code the other functions display nothing!
My First thought is it can be something about std and output error. Some softwares dump some informations on std out and some in std error. When you are not redirecting std error to std out, most of the system calls only returns the stdout part. It sounds thats why you see the whole output in terminal and can't in the system calls.
So try with
/usr/local/bin/chbg -mt 2>&1
Edit:
Also for a temporary work through, you can try some other things. For example redirect the output to file next to the script and read its contents after executing the command, This way you can use the exec:
exec("usr/local/bin/chbg -mt 2>&1 > chbg_out");
//Then start reading chbg_out and see is it work
Edit2
Also it does not make sense why others not working for you.
For example this piece of code written in c, dumps a string in stderr and there is other in stdout.
#include <stdio.h>
#include<stdlib.h>
int main()
{
fputs("\nerr\nrro\nrrr\n",stderr);
fputs("\nou\nuu\nuttt\n",stdout);
return 0;
}
and this php script, tries to run that via exec:
<?php
exec("/tmp/ctest",&$result);
foreach ( $result as $v )
{
echo $v;
}
#output ouuuuttt
?>
See it still dumps out the stdout. But it did not receive the stderr.
Now consider this:
<?php
exec("/tmp/ctest 2>&1",&$result);
foreach ( $result as $v )
{
echo $v;
}
//output: errrrorrrouuuuttt
?>
See, this time we got the whole outputs.
This time the system:
<?php
echo system("/tmp/ctest 2>&1");
//output: err rro rrr ou uu uttt uttt
?>
and so on ...
Maybe your chbg -mt writes additional code to stderr instead of stdout? Try to execute your script inside php like this:
/usr/local/bin/chbg -mt 2>&1
The other responses are good for generic advice. But in this specific case, it appears you are trying to change your background on your desktop. This requires many special considerations because of 'user context':
First, your web server is probably running as a different user, and therefore would not have permissions to change your desktop.
Second, the program probably requires some environmental variables from your user context. For example, X programs need a DISPLAY variable, ssh-agent needs SSH_AGENT_PID and SSH_AUTH_SOCK, etc. I don't know much about changing backgrounds, but I'm guessing it involves D-Bus, which probably requires things like DBUS_SESSION_BUS_ADDRESS, KONSOLE_DBUS_SERVICE, KONSOLE_DBUS_SESSION, and KONSOLE_DBUS_WINDOW. There may be many others. Note that some of these vars change every time you log in, so you can't hard-code them on the PHP side.
For testing, it might be simpler to start your own webserver right from your user session. (i.e. Don't use the system one, it has to run as you. You will need to run it on an alternate port, like 8080). The web server you start manually will have all the 'context' it needs. I'll mention websocketd because it just came out and looks neat.
For "production", you may need to run a daemon in your user context all the time, and have the web server talk to that daemon to 'get stuff done' inside your user context.
PHP's system only returns the last line of execution:
Return Value: Returns the last line of the command output on success, and FALSE on failure.
You will most likely want to use either exec or passthru. exec has an optional parameter to put the output into an array. You could implode the output and use that to echo it.
switch($_REQUEST['do'])
{ case 'test':
exec('/usr/local/bin/chbg -mt', $output);
echo implode('\n', $output); // Could use <br /> if HTML output is desired
break;
}
I think that the result of execution, can changes between users.
First, try to run your PHP script directly into your terminal php yourScript.php
If it runs as expected, go to your Apache service and update it to run with your own credentials
You are trying to change the backgrounds for currently logged in users... While they are using the desktop. Like while I'm typing this message. I minimize my browser and 'ooh my desktop background is different'. Hopefully this is for something important like it turns red when the reactor or overheating.
Anyway to my answer:
Instead of trying to remotely connect and run items as the individual users. Setup each user to run a bash script (in their own account, in their own shell) on a repeating timer. Say every 10 minutes. Have it select the SAME file.. from a network location
/somenetworkshare/backgrounds/images/current.png
Then you can update ALL nodes (1 to a million) just by changing the image itself in /somenetworkshare/backgrounds/images/current.png
I wrote something a while ago that does just this -- you can run a command interpreter (/bin/sh), send it commands, read back responses, send more commands, etc. It uses proc_open() to open a child process and talk to it.
It's at http://github.com/andrasq/quicklib, Quick/Proc/Process.php
Using it would look something like (easier if you have a flexible autoloader; I wrote one of those too in Quicklib):
include 'lib/Quick/Proc/Exception.php';
include 'lib/Quick/Proc/Exists.php';
include 'lib/Quick/Proc/Process.php';
$proc = new Quick_Proc_Process("/bin/sh");
$proc->putInput("pwd\n");
$lines = $proc->getOutputLines($nlines = 10, $timeoutSec = 0.2);
echo $lines[0];
$proc->putInput("date\n");
$lines = $proc->getOutputLines(1, 0.2);
echo $lines[0];
Outputs
/home/andras/quicklib
Sat Feb 21 01:50:39 EST 2015
The unit of communication between php and the process is newline terminated lines. All commands must be newline terminated, and all responses are retrieved in units of lines. Don't forget the newlines, they're hard to identify afterward.
I am working on a project that uses Terminal A on machine A to output to Terminal B on Machine B, both using linux for now. I didnt see it mentioned, but perhaps you can use redirection, something like this in your webserver:
switch($_REQUEST['do'])
{ case 'test':
#process ID on the target (12345, 12346 etc)
echo system('/usr/local/bin/chbg -mt > /proc/<processID>/fd/1');
#OR
#device file on the target (pts/0,tty0, etc)
echo system('/usr/local/bin/chbg -mt > /dev/<TTY-TYPE>/<TTYNUM>');
break;
}
Definitely the permissions need to be set correctly for this to work. The command "mesg y" in a terminal may also assist...Hope that helps.
I'm trying to send a codebar to a thermal printer via shell_excec(), the variable 'a' contains the route of the desired code and the code name itself.
I'm working on localhost.
My problem is that this chunk of code is properly executed in GNU/Linux (Trisquel) but when I switch to OsX it won't work
My first guess was that the file didn't had the proper permissions, but already checked and that's not the problem.
<?php
$cod =$_POST["a"];
$salida = shell_exec('lpr '.$cod);
echo $salida.' lpr '.$cod;
?>
Try add 2>&1 to end of you comand to exec:
shell_exec('lpr '.$cod.' 2>&1');
It may help tp you get more data from output produced by lpr
I have a shell script deploy.sh that has the following content:-
echo "0 Importing the code"
eval "git pull -u origin master"
echo "1 Backing up existing data in database.."
// -- other code follows here
When I execute the script directly using the terminal, I get the following output:-
0 Importing the code
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From bitbucket.org:user/repo
* branch master -> FETCH_HEAD
Updating db13xxx..6705xxx
1 Backing up existing data in database..
This is correct. However, I wrote a PHP script with which I can invole the deploy.sh script over http. Content of this php page is as follows:-
$output = `./deploy.sh`;
echo '<pre>', $output, '</pre>';
When I invoke this php file through the browser, the shell script is in fact getting invoked and I'm getting the following output:-
0 Importing the code
1 Backing up existing data in database..
The problem is that the eval "git pull -u origin master" command didnt get executed and its output is not shown. Any idea what the problem is?
This works
<?php
$output = shell_exec('sh deploy.sh');
echo "$output";
?>
Before that make sure that file has chmod 777 permission.
One thing you can do with the exec() function is to pass two optional values for more insight.
Here's some code I use to test shell scripts from a web interface.
<?php
require_once(__DIR__.'/../libs/Render.php');
error_reporting(E_ALL);
//Initialize and Run Command, with a little trick to avoid certain issues
$target='cd ../../your/relative/path && ./CustomScript.sh';
$outbuf=exec($target,$stdoutbuf, $returnbuf);
//Structure
$htm= new renderable('html');
$html->children[]= $head= new renderable('head');
$html->children[]= $body= new renderable('body');
$body->children[]= $out= new renderable('div');
$body->children[]= $stdout= new renderable('div');
$body->children[]= $returnout= new renderable('div');
//Value
$out->content= 'OUTPUT: '.$outbuf;
$stdout->content= 'STDOUT: '.var_export($stdoutbuf,true);
$returnout->content= 'RETURN: '.$returnbuf; //127 == Pathing problem
//Output
print_r($html->render());
?>
File is using the renderable class from the project I use this in, but you can put the string output wherever you are using it or echo/print_r() just as well. Also make sure you're not in safe mode by running phpinfo(); lots of folks having that issue.
Additionally, there's no reason you should avoid using shell scripts in PHP. PHP being a scripting language, it is quite thrifty at aggregating many shell scripts to allow higher-level administration.
PHP isn't only for 'web sites'. Even then, exposing administrative scripts to web interfaces is quite useful in and of itself; occasionally this is even a project requirement.
You should try to avoid running shell commands in php.
Having said that, try this:
$output = shell_exec('./deploy.sh');
echo "<pre>".$output."</pre>";
As per: http://www.php.net/manual/en/function.shell-exec.php
This is the correct code
<?php
$cmd = 'ifconfig'; // pass command here
echo "<pre>".shell_exec($cmd)."</pre>";
?>
I am trying to run a R script from PHP, and in R script, I will create test.jpg image, and in PHP, I will display this image on web.
The R is 2.11.1 and OS is Ubuntu 10.10.
The problem is: this .jpg is created successfully if I run from terminal, but no image created if I run from WebUI. I run the script from terminal and WebUI in the same directory. /opt/lampp/htdocs/name/. (If somebody can tell me a good tool to debug this WebUI, it would be great. I put some echo in the .php file, I see the functions being called, but still do not know how to solve this bug).
The .jpg is created when I run from terminal:
php r_caller.php
In this r_caller.php, I have simple function as:
<?php php_call_r(){
$cmd = "echo 'argv <- \"r_command.r\"; source(argv)' | " .
"/usr/bin/R --vanilla --slave";
$ret = system($cmd);
echo $ret;}
?>
and this php_call_r function is called in the same file as r_caller.php:
<?php
//some irrelavant codes above
php_call_r();
print("<img src=test.jpg>");
?}
and in the r_command.r script, I have simple commands as:
jpeg("test.jpg")
plot(50, 50)
dev.off()
I really appreciate your help!
You did not specify your platform and R version, but on unix the jpeg() device may require X11 to render the image (which you may have in your interactive session but not in apache). You may be better off using the Cairo package or other means that don't require X11 session (recent R allows you to use alternative types in the jpeg call which you can also try - see ?jpeg).
(As a side note there is a PHP client to Rserve which makes web requests much faster - running R itself is pretty much the slowest way to use R from PHP. If you don't want to install any packages then you may want to use at least Rscript)
Edit: Now that you have added the R version - that's a really ancient one, you should seriously consider upgrading it. You can try installing Cairo with that old R version, but you may possibly need to go back there as well.
One more thing to consider, check you file privileges - make sure www-data has write-permissions wherever you will be creating the file (e.g., see echo system("pwd"); for the current directory R will be run in).
Check the Apache error logs to see if there are any errors. Try adding the following to the beginning of your PHP code:
error_reporting(E_ALL);
ini_set('display_errors','On');
This might be a copy/paste error, but your php_call_r function is not properly defined as a function. I suggest the following:
<?php function php_call_r() {
$cmd = "echo 'argv <- \"r_command.r\"; source(argv)' | " .
"/usr/bin/R --vanilla --slave";
$ret = system($cmd);
echo $ret;
}
?>
Executing R from PHP for each request is a very bad idea -- PHP piping is usually not reliable and R's output is optimized for interactive work rather than transmitting results. Moreover R starts for ages, so you waste lots of time and CPU power.
The better idea is to use R worker daemon, created by either Rserve or triggr -- Rserve has PHP client, for triggr you need to cook one on your own, but it is trivial; it may look like this:
R part (r.R)
require(triggr);
serve(function(data_from_php){
cat(sprintf("Called with: %s\n",data_from_php));
#<<Picture creation code>>
#Break connection notifying PHP that picture is done
return(endConnection("Done\r\n"));
},9090);
# ^- Port you want to use for internal communication
PHP part
<?php
$s=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
echo "Connecting...\n";
if(socket_connect($s,"localhost",9090)){
echo "Connected!\n"; //v double \r\n is crucial
$d="some data for R\r\n\r\n";
socket_write($s,$d,strlen($d));
//This blocks until picture is done
$r=socket_read($s,6);
//Here we can emit the page featuring <img>
echo "Response was $r\n";
}
?>
Now you just fire r.R in background or under some auto-resurrection daemon and you are done.
I'm having trouble executing the lessc compiler from PHP. I'm using Symfony, and have tried using the sfLESSPlugin, but have been unsuccessful. I've put my code in a filter that executes before the page renders, so that every time the page is refreshed, my LESS files are compiled into one CSS file (don't want to have recompile manually every time I make a change, at least while I'm developing). Here are the different variations that I've attempted:
$fs = new sfFilesystem();
$command = '/Users/jordanb/node/node_modules/less/bin/lessc less/bootstrap.less css/bootstrap.css';
try
{
$fs->execute($command, null, array($this, 'throwCompilerError'));
}
catch (RuntimeException $e)
{
return false;
}
This returns an error: "Problem executing command", with an error code of 127. Digging deeper into Symfony's execute(), it calls proc_open() and then proc_close(). Some research online told me that an error code of 127 means that the command was not found.
Running the exact same command on the command line works just fine.
To be extra sure, I executed chmod 777 on /Users/jordanb/node/node_modules/less/bin/lessc, just to make sure it wasn't a permissions issue. Still didn't work.
I also tried just "lessc" instead of the full path, which didn't work. I've added lessc to my classpath, so typing "which lessc" gives me "/Users/jordanb/node/node_modules/less/bin/lessc".
I also tried a simple:
shell_exec('lessc less/bootstrap.less css/bootstrap.css');
which didn't seem to do anything. I printed the output to the PHP error log as well as to a text file, and the output was empty in both cases. I also tried using the full path in this case.
You can make a shell script that compiles things the way you want:
compile_css.sh
/Users/jordanb/node/node_modules/less/bin/lessc less/bootstrap.less css/bootstrap.css
Then
chmod +x compile_css.sh
And finally call it from your script
$command = '/path/to/compile_css.sh';
This will give you more control over what you can execute, but if you still want to do it from php, try this:
$command = '/Users/jordanb/node/node_modules/less/bin/lessc "less/bootstrap.less css/bootstrap.css"';
// note the quotes around the arguments.