Redirect PHP-Shell-Script output - php

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.

Related

How to run external php script using Php shell_exec?

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.

How to email output from shell_exec()?

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 !

Is it time consuming to print log in exec command?

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.

What exactly does this PHP code do? system("php ./somescript.php $something >/dev/null &");

system("php ./somescript.php $something >/dev/null &");
I'm new to PHP and I am deciphering someone else's code and can't figure out what this code is doing. I looked at the system documentation here so I understand that it will execute the PHP script in somescript.php, and that $something is a parameter passed to that script...but after that I'm lost.
Also, what part of the script does $something get passed to? How does it know what function in somescript.php to call first?
You are correct about it executing the script with $something passed as parameter. The > /dev/null is just piping the output into a black hole (i.e. suppressing it). The & part launches the script in the background.
system("php ./somescript.php $something >/dev/null &");
can be split up as:
system(
This is the php function to execute a command in shell
system("php
We are asking the php command line interpreter to be run
system("php ./
we are asking the interpreter to look in current directory using ./
system("php ./somescript.php
we are saying that the php file to be executed in somescript.php
system("php ./somescript.php $something
we are passing $something which is a variable in the script running system() as an argument into the script somescript.php
system("php ./somescript.php $something >/dev/null
we are saying that the output should be sent to /dev/null ..which basically means do not print any output on the screen. > is the redirection command. So > /dev/null means redirect output to /dev/null which is like an alias for a "null device" or simply..nothing.
system("php ./somescript.php $something >/dev/null &");
Lastly we are asking the script to be run in the background using & which means as soon as the script starts, control is returned back to the shell
It's basically running the ./somescript.php program, with $something as a command-line parameter.
It explicitly ignores the output by routing it to the null device.
And it runs it in its own shell and doesn't wait for it to finish (that's the & bit on the end).
I assume that somescript.php is a program that runs some kind of background task. It probably takes a bit of time to run, but your main program doesn't need to know about the results of that task, so it doesn't need to wait for it to finish.
[EDIT]
$something is passed into the program as a command-line argument. When PHP is called from the command line, the arguments are populated into the $argv array.
See the PHP manual for more info:
http://php.net/manual/en/reserved.variables.argv.php
http://php.net/manual/en/features.commandline.php
1 - system: execution of an external program from PHP
2- php ./somescript.php $something: PHP cli execution of a script called ./somescript.php with one argument being $something.
3 - >/dev/null: redirects stdout to /dev/null which means you won't see standard output, but you will still see stderr. More info on output redirections. That's pure UNIX nothing to do with PHP.
4 - &: sends command in the background so that PHP execution can continue without having to wait for the external program to complete. Once again, pure UNIX, nothing to do with PHP per se. More info.

Can't execute PHP script using PHP exec

I am trying to invoke a script which takes several seconds (web services with 3rd party) using the PHP exec call. After much struggling, I reduced this to the classic hello world example. The calling script looks like:
exec('/usr/bin/php /home/quote2bi/tmp/helloworld.php > /tmp/execoutput.txt 2>&1 &');
When I run this, the output execoutput.txt contains a copy of the invoking script page, not hello world as I expected.
Why can't I get this PHP script to execute using exec? Note that when I change the command to something like ls -l, the output is a directory listing as expected. btw, in case it matters, I did chmod the called script to 755...
Update - I moved the exec call to the end of the calling script and at least now I don't see the calling script executed in the output. Thx to posters and I will try some of these ideas.
Help!
Thanks
Steve
I had this issue also and it turns out this is a bug in php (#11430). The fix is to use php-cli when calling another php script within a php script. So you can still use exec but rather than use php use php-cli when calling it in the browser:
exec("php-cli somescript.php");
This worked for me.
What exec is doing is taking the rightmost command and appending it to your destination. If you have the shebang line in your php script, you shouldn't need to include the binary directive of the php interpreter.
if you just want the script's output, try:
exec('/home/quote2bi/tmp/helloworld.php > /tmp/execoutput.txt 2>&1 &')
however if you do not want the errors to be in the file, you should redirect the STDERR prior to outputting to the file. Like so:
exec('/home/quote2bi/tmp/helloworld.php 2> /dev/null > /tmp/execoutput.txt')
the above should only output the "Hello World" to the execoutput.
Edit:
Interesting you are getting this behaviour. You stated the command "ls" worked. Try making an alias for this and forward it to a file like so:
alias pexec='php /home/quote2bi/tmp/helloworld.php'
then
exec('pexec > /tmp/execoutput.txt 2>&1 &')
it seems to be a problem with the way exec handles input as opposed to the shell itself.
-John
The problem is with PHP itself, it treats everything as $argv in the script. It doesn´t redirect the output to a file ou to /dev/null.
I faced the same problem some time ago. What I did is to create a runscript.php in /opt/php-bin and then inside this script run what It should be running. Something like this:
$script = $argv[1]
$params = implode(' ', array_slice($argv, 2));
$cmd = "{$script} {$params} > /dev/null &";
$output = array();
$return = 0;
exec("php {$cmd}", $output, $return);
exit((int)$return);
And then you call it using:
exec('/opt/php-bin/runscript.php /path/to/your/script.php arg1 arg2')
It´s the only way I managed to get this working.
To avoid the stated problems of PHP in this area, why not put this in inside a shell script? PHP can then execute the shell script which has all the redirections handled internally.
If you need to dynamically change things, then why not write the shell script and then execute it (and of course, clean up afterwards)?
if you are just simply running a php script one possible way to execute the entire code is to use the include() that will run the php file and output any results. You cannot direct the output to a text file but it should appear in the browser window if you're Hello World php script looks like
<?php echo "Hello World!"; ?>
then it will spit that out in the browser. So your second code would look like
<?php include("helloWorld.php"); echo " PHP ROCKS";?>
resulting in a page that would look like,
Hello world! PHP ROCKS
This runs as if you run the script from browser.
This came across while working on a project on linux platform.
exec('wget http://<url to the php script>)
Hope this helps!!

Categories