In PHP,
I am running exec command in php script so that It will run in background. But I'm wondering about the performance hit when logging to log_file?
exec("/usr/bin/php /path/to/Notification.php >> /path/to/log_file.log 2>&1 &");
If so then how can I not print output to log_file? I know /dev/null. But I don't know correct syntax or structure. Please Can anyone append me this on above line.
Any help will be appreciated.
since you are appending to the log file through the bash output redirection, it will be very good in terms of performance.
Everything depends ofcourse on how much output that is being logged and how big your log file is, if you aren't rotating it properly.
If this is too excessive, you can disable the output redirection, simply by removing everything after the >> output redirection directive:
exec("/usr/bin/php /path/to/Notification.php &");
this however could still output to the system's stdout or stderr, to skip this redirect all output to /dev/null as you mentioned:
exec("/usr/bin/php /path/to/Notification.php &> /dev/null &");
here is a good reference about output redirection in bash
please also note that $> is bash only.
Related
I have the following code on my index.php file. But it is not working properly.. When i directly visit domain.com/script.php it works. I need this script to be executed in the background while accessing index page. Can anyone help me?
shell_exec('php script.php > /dev/null 2>/dev/null &');
check php is running in safe mode or not shell_exec is disabled in safe mode for the sake of security why don't you use
curl
to run the code
Well I think there are 2 possible issues in your case
1) try this:
shell_exec("script.php 2>/dev/null >/dev/null &");
OR
shell_exec("script.php 2>&1 | tee -a /tmp/mylog 2>/dev/null >/dev/null &");
2) A simple way to handle the problem of capturing stderr output when using shell-exec under windows is to call ob_start() before the command and ob_end_clean() afterwards
ob_start();
ob_end_clean();
Well instead of using shell_exec, you can make an ajax call to script.php when the user visits index.php.
Another option is to run the script.php as a cron job every 5 minutes or so. When the user visits index.php, some data can be saved to database indicating that script.php should run. script.php should check if it is marked for running.
With cron jobs, the output of the file being executed is emailed to me. I recently discovered via this answer that it's possible to asynchronously execute a PHP file using the shell_exec() function. Per the above answer, I've been using the following command:
shell_exec('php /file/path.php parameter1 parameter2 > /dev/null 2>/dev/null &');
I think what is of most interest with regards to this question is the stuff at the end:
> /dev/null 2>/dev/null &
Is there any way to change that so that the output is emailed, like with a cron job?
The line
> /dev/null 2>/dev/null &
Essentially sends the output to a null file. If you take that bit off, the output will be sent to the standard out, which should in turn should email you the results assuming you run it with a cron job.
So,
shell_exec('php /file/path.php parameter1 parameter2');
If you're not running it with a cron job, you'll need to build in the email functionality to the script itself.
First off, shell_exec() is not asynchronous. Execution of the PHP code will be suspended until the shell_exec() call has terminated.
This: > /dev/null tells the shell to redirect stdout from the process being executed to /dev/null, which means it disappears. This: 2> /dev/null does the same, but for stderr in stead of stdout.
If you remove these parts of the shell_exec() call, the call will return whatever is written to stdout:
$result = shell_exec('php /file/path.php parameter1 parameter2');
mail('me#email.com', 'Shell output', $result);
There are also other alternatives to shell_exec() that may suit your needs better. For example popen()andproc_open()` allow more fine grained control over input and output.
Also, since you are executing a PHP script, you may be able to simply use include() or require(), depending on how the script is written. Another option would be to read the file and then execute the PHP code using eval().
Use :
| mail -s "Result of cron job" myemail#company.com
At the end of your command. Also, you can pipe stderr and stdout into stdout 2> &1 | mail....
That should do the trick. Maybe because you use shell_exec("... &"), you'll have to wrap the whole php /file/... | mail -s "result" myemail#company.com in a subshell. like:
shell_exec('(php /file/path.php parameter1 parameter2 2> &1 | mail -s "Result of cron job" myemail#company.com) &')
This is a rather ugly way to get the output to send a message and I'd advise in favor of refactoring the outer call of shell_exec to read stderr and stdout, craft a message and send that to yourself. Meanwhile the | mailsolution should do the trick.
Happy mailing !
For a website, I need to be able to start and stop a daemon process. What I am currently doing is
exec("sudo /etc/init.d/daemonToStart start");
The daemon process is started, but Apache/PHP hangs. Doing a ps aux revealed that sudo itself changed into a zombie process, effectively killing all further progress. Is this normal behavior when trying to start a daeomon from PHP?
And yes, Apache has the right to execute the /etc/init.d/daemonToStart command. I altered the /etc/sudoers file to allow it to do so. No, I have not allowed Apache to be able to execute any kind of command, just a limited few to allow the website to work.
Anyway, going back to my question, is there a way to allow PHP to start daemons in a way that no zombie process is created? I ask this because when I do the reverse, stopping an already started daemon, works just fine.
Try appending > /dev/null 2>&1 & to the command.
So this:
exec("sudo /etc/init.d/daemonToStart > /dev/null 2>&1 &");
Just in case you want to know what it does/why:
> /dev/null - redirect STDOUT to /dev/null (blackhole it, in other words)
2>&1 - redirect STDERR to STDOUT (blackhole it as well)
& detach process and run in the background
I had the same problem.
I agree with DaveRandom, you have to suppress every output (stdout and stderr). But no need to launch in another process with the ending '&': the exec() function can't check the return code anymore, and returns ok even if there is an error...
And I prefer to store outputs in a temporary file, instead of 'blackhole'it.
Working solution:
$temp = tempnam(sys_get_temp_dir(), 'php');
exec('sudo /etc/init.d/daemonToStart >'.$temp.' 2>&1');
Just read file content after, and delete temporary file:
$output = explode("\n", file_get_contents($temp));
#unlink($temp);
I have never tried starting a daemon from PHP, but I have tried running other shell commands, with much trouble. Here are a few things I have tried, in the past:
As per DaveRandom's answer, append /dev/null 2>&1 & to the end of your command. This will redirect errors to standard output. You can then use this output to debug.
Make sure your webserver's user's PATH contains all referenced binaries inside your daemon script. You can do this by calling exec('echo $PATH; whoami;). This will tell you the user PHP is running under, and it's current PATH variable.
I need to run a command in PHP like this:
exec('dosomething > saveit.txt');
Except I don't want PHP to wait for it to be complete. I also don't want to throw away the output, and I don't want to use nohup because I'm using that for something else in the same directory.
I also tried pclose(popen('dosomething > saveit.txt','r')); and that didn't work, it still waited.
Add an ampersand to the end of the command, so:
exec('dosomething > saveit.txt &');
in the documentation of exec() there is an interesting comment that says:
Took quite some time to figure out the line I am going to post next. If you want to execute a command in the background without having the script waiting for the result, you can do the following:
<?php
passthru("/usr/bin/php /path/to/script.php ".$argv_parameter." >> /path/to/log_file.log 2>&1 &");
?>
i have got a php-script foo.php
#!/usr/bin/php -c /etc/php5/cli/php.ini -q
<?php
echo 'hello'; // & do some stuff
?>
I call this script not wrapped by a sh-script but using it directly in a cron job.
To get rid of it's output i normally would just create a sh-file which calls
/usr/bin/php -c /etc/php5/cli/php.ini -q foo.php > /dev/null 2 > /dev/null
now i'd like to do this in the interpreter-declaration of the php file it self...
so i am looking for the syntax for:
#!/usr/bin/php -args [file's content] > /redirect 2 > /redirect
i have kind of a hard time googleing for it... so if anybody could point me into the right direction i would really appreciate it!
Thx in advance
Corelgott
The shebang statement was never intended to control the output of the script, it's more of a use this program to execute what's underneath here type deal, as such there's no option for what you want.
Unless the interpreter itself has an output argument (which the php cli doesn't), you will need to keep the > /dev/null statement in the crontab line.
You could also modify your scripts to have a global boolean $output, surrounding all print statements with if statements and include that at the top of the file.
Like, #Victor Stanciu said, you redirect the output directly in the cron job command, but the only other way I can think of is:
php -r "ob_start(); include 'my_script'; ob_end_clean();"
I think you could close stdout with fclose(STDOUT), but apparently the constants STDIN, STDOUT and STDERR no longer exist.