I'm calling a php script using CRON.
The script use a lot the error_log function :
error_log('My error');
Seems like it's not working from CLI.
I can make it work by using more arguments :
error_log('My error', 3, '/fullpath/to/my/log');
But I would like to avoid modifying everything (my script include a lot of other scripts).
As far as I understand, PHP is using a different php.ini when called from command line.
Is there a way to force it to use the normal php.ini ?
I need my cron to execute this script in the exact same environment that from the web.
Are there problems I should be aware of ? Others differences that could break my code ?
Edit :
I found a way to tell php which php.ini file to use (-c):
/path/to/php5 -c /path/to/php.ini /path/to/script.php
But it's not working.
In my script shell_exec('php --ini') is still showing cli/php.ini...
If you need your cron to execute this script in the exact same environment that from the web, just call it from the web:
setup a virtual host (local only, e.g. on port 4242, locked with iptables)
run cron as curl http://localhost:4242/script.php
It will run the script as a webserver user, using all environment variables, configs, and logs.
To solve the exact problem with logging, just redirect stderr to a file:
/path/to/php5 /path/to/script.php 2> /fullpath/to/my/log
The lst part: shell_exec('php --ini') shows default cli/php.ini because you start new process with default config. To show custom config either specify it in the command line
shell_exec('php --ini -c /path/to/php.ini')
or show info for current process:
phpinfo(INFO_GENERAL)
Related
I am trying to do simple web service in PHP (I use Laravel) to restart and shutdown my raspberry pi.
I tried in my PHP service call something like this:
exec("putty -ssh pi#192.168.0.12 -pw myPassword -m D:\workspace\CPS\public\ssh\restart.txt");
In my restart.txt I have simple command sudo shutdown -r now
but when I call my web service in Advanced Rest Client Application (Chrome addon), my request is processing and never ending. In command line this works properly.
I thought that the problem is with running PuTTy directly in PHP and I do some changes and create .bat file with the following content:
echo off
putty -ssh pi#%1 -pw %2 -m %3
I start this batch script like this:
exec("D:\workspace\CPS\public\ssh\restart.bat 192.168.0.12 myPassword D:\workspace\CPS\public\ssh\restart.txt");
...but result is the same. I changed my web service to GET method and call service in the browser like page but nothing change.
I haven't any error/exception in log files and in console. I also checked the system log but nothing found.
Am I doing something wrong or missed something? It is possible or there is a better way to achieve this?
Currently I run it on Windows 7 and XAMPP. I will do second version for Linux in future and decide in code which command should I run depends on current environment.
Update
I forgot to wrote, all required users have permissions to execute files in my (...)/ssh directory
Try to use:
echo system("D:\workspace\CPS\public\ssh\restart.bat 192.168.0.12 myPassword D:\workspace\CPS\public\ssh\restart.txt");
to get output. May be you find something error.
And you need to check safe_mode options in your php.ini file (like disable_functions and safe_mode_exec_dir).
And try to use FULL path to your putty.exe file. Webserver work's in another directory, than your bat file.
This is really simple but I cannot get it to work at all. Spent many hours and I've always give up. I created php script called copy.php and it should call a python script called copy.py.
I want to execute a command line like this
<?php exec('/var/www/html/copy.py'); ?>
Really simple.
Why cannot I get the python script executed from php exec()? The function inside python script is to get a copy of error_log from a different directory (outside of Apache) into html directory.
If I run that from a terminal
> php copy.php
It did execute the function and made a copy. Why is that the web browser isn't doing it?
Let me simplify this:
why cannot exec("cp /var/log/httpd/error_log /var/www/html/path/to/php/script") work?
it works fine if I type it in terminal but not when run in a browser.
As others have alluded to, the difference is probably permissions. When you run a command from the command line, you're generally not the same users as your apache script is running as.
Put another way, if from the command line you type whoami, you'll probably get whatever name your user account is.
The echo exec('whoami'); from within php shows who the script is running as, which is Apache.
So, whatever command you're trying to run from your web server isn't available to run as the Apache user. You mentioned you've been able to have exec("python /usr/diskpurge/script.py") work, but not to have exec('/var/www/html/copy.py') doesn't. This is due to in one instance you're running python, in the other you're trying to execute your copy.py script. If copy.py doesn't have execute permissions for the Apache user, you're not going to be able to run it from the browser.
Perhaps different settings apply for the Apache environment versus the command line.
Use error_reporting(E_ALL); and ini_set('display_errors', true) to see what errosr may come up.
It is possible that the Apache environment is prohibited from using exec or the fact that Apache runs under a different user that does not have execute rights on the python script.
sounds like a permission error. Check if your server is running with sufficient rights.
echo exec('whoami');
Set your error reporting to report all:
ini_set('display_errors', true);
error_reporting(E_ALL);
and check for errors..
If your whoami returns a user which is not a member of the SU family (linux) or administration (windows) then resite your permissions..
Linux:
Assign the user returned by whoami correct permissions to run python scripts.. Do not allow the resulted username to run as root with total administration powers.. This is a big no no
The only reason its not working is because you didn't set the write permissions!
Do:
sudo nano /etc/sudoers
And then put the following:
www-data ALL=(root) NOPASSWD:ALL
I am having difficulty with the PHP exec() function. It seems to not be calling certain functions. For instance, the code echo exec('ls'); produces no output whatsoever (it should, there are files in the directory). That main reason this is a problem for me is that I'm trying execute a .jar from a PHP exec() call.
As far as I know I'm calling the java program properly, but I'm not getting any of the output. The .jar can be executed from the command line on the server. (For the record, it's an apache server).
My php for the .jar execute looks like this:
$output = array();
exec('java -jar testJava.jar', $output);
print_r($output);
All I get for output from this exec() call is Array().
I have had success with exec() executing 'whoami' and 'pwd'. I can't figure out why some functions are working and some aren't. I'm not the most experienced person with PHP either, so I'm not too sure how to diagnose the issue. Any and all help would be appreciated.
The reason why you are not able to execute ls is because of permissions.
If you are running the web server as user A , then you can only ls only those directories which have permissions for user A.
You can either change the permission of the directory or you can change the user under which the server is running by changing the httpd.conf file(i am assuming that you are using apache).
If you are changing the permissions of the directory, then make sure that you change permissions of parent directories also.
To change the web server user, follow following steps:
Open the following file:
vi /etc/httpd/conf/httpd.conf
Search for
User apache
Group apache
Change the user and group name. After changing the user and group, restart the server using following command.
/sbin/service httpd restart
Then you will be able to execute all commands which can be run by that user.
EDIT:
The 'User' should be a non-root user in httpd.conf. Apache by default doesnot serve pages when run as root. You have to set user as a non-root user or else you will get error.
If you want to force apache to run as root, then you have to set a environment variable as below:
env CFLAGS=-DBIG_SECURITY_HOLE
Then you have to rebuild apache before you can run it as root.
I have found the issue - SELinux was blocking PHP from accessing certain functions. Putting SELinux into permissive mode has fixed the issues (although, I'd rather not have to leave SELinux in permissive mode; I'd rather find a way of allowing certain functions if I can).
I have a solution:
command runs from console, but not from php via exec/system/passthru.
The issue is the path to command. It works with the absolute path to command
So that:
wkhtmltopdf "htm1Eufn7.htm" "pdfIZrNcb.pdf"
becomes:
/usr/local/bin/wkhtmltopdf "htm1Eufn7.htm" "pdfIZrNcb.pdf"
And now, it's works from php via exec
Where command binary you can see via whereis wkhtmltopdf
Tore my hair out trying to work out why PHP exec works from command line but not from Apache. At the end, I found the following permissions:
***getsebool -a | grep httpd*** ---->
**httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off**
USE: setsebool -P httpd_ssi_exec 1
SEE: https://linux.die.net/man/8/httpd_selinux
Your problem is not an execution issue but the syntax of the exec command. The second argument is always returned as an array and contains a single line of the output in each index. The return value of the exec function will contain the final line of the commands output. To show the output you can use:
foreach($output as $line) echo "$line\n";
See http://php.net/manual/en/function.exec.php for details. You can also get the command's exit value with a third argument.
I am having an issue using the PHP function shell_exec().
I have an application which I can run from the linux command line perfectly fine. The application takes several hours to run, so I am trying to spawn a new instance using shell_exec() to manage better. However, when I run the exact same command (which works on the command line) through shell_exec(), it returns an empty string, and it doesn't look like any new processes were started. Plus it completes almost instantly. shell_exec() is suppose to wait until the command has finished correct?
I have also tried variations of exec() with the same outcome.
Does anyone have any idea what could be going on here?
There are no symbolic links or anything funky in the command: just the path to the application and a few command line parametes.
Some thing with you env
See output of env from cli (command line interface) and php script
Also see what your shell interpreter?
And does script and cli application runs from one user?
If so, se option safe_mode
Make sure the user apache is running on (probably www-data) has access to the files and that they are executable (ls -la). A simple chmod 777 [filename] would fix that.
By default PHP will timeout after 30 sec. You can disable the limit like this:
<?php
set_time_limit(0);
?>
Edit:
Also consider this: http://www.rabbitmq.com/
i want to execute a php script every day. i have a bash script containing below lines. and i was doing it with that script. but by this way, it can be executed from another computer. lets say webservername="slmnbr" any body can call myscript with
xhttp://slmnbr/myscript.php.
i want to call it from just server.
BASE_URL=http://`get-webservername`
/usr/bin/wget --no-check-certificate --timeout=0 -O - "$BASE_URL/myscript.php"
thanks in advance
You need to have PHP CLI (command line interface) to do this. It often comes with the PHP installation package (or a separate package).
So as #James mentioned it you need to precede you script name with the CLI PHP executable which in windows is php.exe somewhere in your install directory.
In UN*X systems it's somewhere in /usr/bin or /usr/local/bin or /opt/local/bin. If it is in the PATH you can simply execute it like this:
php your_script.php
But keep in mind that running your script from server will be not the same as running from a webserver. For e.g. you won't have the POST or GET variables. So your script may not work.
Update
You can make the cron ran scripts unreachable for your webserver by making it unreadable by the user who is running the PHP scripts by the http daemon (usually www-data).
I recommend to make it readable only by the user who is running it from cron:
chown cronuser your_script.php
chmod 0400 your_script.php
Update2
If you're running your script in cron with the same user as the webserver does, then at the top of your script stop it from being executed:
if (!(php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']))) {
header('HTTP/1.1 403 Forbidden');
exit;
}
To execute a task(or a php script) every day use cron.
The link has all the info you need, including how to prevent external access.
With any recent version of "php" you should get a standalone executable called:
"php.exe"
Just execute this like so:
/usr/local/php.exe your_script.php