shell cron job to run a php file - php

I need to create a cron job where I only have shell access. I know how to do it with cPanel, but this is on 1and1 server so I must use shell.
I got to the part where I add a new cron job in the crontab as per 1and1 FAQ, but I'm not sure what I'm doing wrong because the cron job isn't running at all.
This is what I'd normally put in cPanel:
0 8 * * 1 wget 'http://my_www_domain/googlefroogle.php?feed=fy_uy_tp&key=XXXXX3f7d1'
This is what I have in my crontab now:
0 8 * * 1 /usr/local/bin/php /homepages/XX/XXXXXXX/htdocs/googlefroogle.php?feed=fy_uy_tp&key=XXXXX3f7d1
What am I missing or doing wrong? BTW, if I manually enter the URL in my browser, everything works fine so I'm sure the script is OK.

As far as I know, you can use wget on a cronjob on any server, so you there should be no problem if you keep using it that way.
Now, the reason it doesn't work it's because you can send GET params to a PHP file that way. PHP handles command line in a different way. See Using PHP from the command line.
So you must check if the php file is called from a url or from command line (it's easy, look at php_sapi_name) and, if that's the case, get the parameters using the command line interface or define them in your script.
if (php_sapi_name() == 'cli') {
if ($argc != 3) {
die(sprintf('Usage: %s <feed> <key>', $argv[0]));
}
$feed = $argv[1];
$key = $argv[2];
}else{
$feed = isset($_GET['feed']) ? $_GET['feed'] : null ;
$key = isset($_GET['key']) ? $_GET['key'] : null ;
}
Now you have to call the script like this on your cronjob:
php -f file.php fy_uy_tp XXXXX3f7d1
What it does, is that if the script is running from command line, it gets the arguments as variables, if not, then it check for the GET parameters to exists and use them.

You can still use your cPanel "command" in crontab manaed via shell.
use
crontab -l
to list current cron jobs.
crontab -e
to edit crontab.You will need to install crontab manually on some minimal installations.

try
*/0 */8 * * */1 /usr/local/bin/php -f /homepages/XX...

You cannot run a file with parameters like that, because the shell is looking for a file named "file.php?param=value", not "file.php".
if the parameters are always the same, you can set them by force in the script:
<?php
$_GET['feed'] = 'fy_uy_tp';
$_GET['key'] = ...
$_REQUEST = $_GET;
?>
and then check that the script doesn't need some other variable, such as $_SERVER['REMOTE_ADDR'] or things like that.

None of these answers helped me do what I need so I ended up using the following php file which was called by the crontab:
$data = array('feed'=>'fy_uy_tp','key'=>'MY_KEY_HERE');
$url = http_build_query($data, '', '&');
$fullurl = 'http://www.MYSITE.com/googlefroogle.php?'.$url;
$ch = curl_init($fullurl);
$fp = fopen("MY_LOG_FILE.txt", "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
In case anyone else needs something similar... Also, note that this requires php5, the http_build_query doesn't work on php4

Related

PHP - Sending request causes test server to freeze [duplicate]

I have a relatively simple script like the following:
<?php
$url = "localhost:2222/test.html";
echo "*** URL ***\n";
echo $url . "\n";
echo "***********\n";
echo "** whoami *\n";
echo exec('whoami');
echo "* Output **\n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
When I execute it on the command line, it works - I get the meager results from within test.html.
When I run this script by loading up the built-in PHP server and browsing to the script, it hangs. No output to the screen, nothing written to the logs.
I read that sometimes user permissions can get in the way, so I tried doing whoami to ensure that the user that ran the built-in PHP server is the same as the one who executed the script on the command line; which they are.
safe_mode is off, disable_functions is set to nothing. I can exec other commands successfully (like the whoami).
What else should I check for? Does the built-in PHP server count as someone other user when it fulfills a request perhaps?
The PHP built-in development web server is a very simple single threaded test server. It cannot handle two requests at once. You're trying to retrieve a file from itself in a separate request, so you're running into a deadlock. The first request is waiting for the second to complete, but the second request cannot be handled while the first is still running.
Since PHP 7.4 the environment variable PHP_CLI_SERVER_WORKERS allows concurrent requests by spawning multiple PHP workers on the same port on the built-in web server. It is considered experimental, see the docs.
Using it, the PHP script can send requests to itself which is already being served, without halting.
PHP_CLI_SERVER_WORKERS=10 php -S ...
Works with Laravel as well:
PHP_CLI_SERVER_WORKERS=10 php artisan serve
I think problem in your $url. It may be look like this $url = "http://localhost:2222/test.html"; or $url = "http://localhost/test.html"; I think it's solve your problem. Thanks for your question. Best of luck.

PHP code not executing in cron job

I've a php script which will get all network card mac address and store first one in a text file.
Here is the code which I used to get MAC of system:
<?php
$mycom = shell_exec("ifconfig | grep HWaddr");
$findVal = "HWaddr";
$mac_arry = array();
while (strpos($mycom, $findVal) > 0) {
$start_pos = strpos($mycom, $findVal);
$mac=substr($mycom,($start_pos+7),17);
$mac_arry[] = $mac;
$mycom = substr($mycom, ($start_pos+10));
}
$fileHandle = fopen("/tmp/mac.txt", "a+");
fwrite($fileHandle, $mac_arry[0]);
fclose($fileHandle);
?>
If I execute this file directly in browser or through terminal, it works perfectly. But when I add this to cron for every minute, it doesn't work. Here is my cronjob:
* * * * * /usr/bin/php -f /var/www/html/test.php
by axiac
The cron job executes in an environment that is very different than the one you get in a terminal. The content of the $PATH variable is shorter and it's possible that /sbin (where ifconfig usually stays) is not included. That makes the shell_exec() call fail and the rest of the script doesn't matter. Use which ifconfig (in a terminal) to find out where ifconfig resides on your system and invoke it using its absolute path in shell_exec(). The same for grep (it probably can be found even without full path because it usually stays in /bin.)

PHP Built-In Server Can't cURL

I have a relatively simple script like the following:
<?php
$url = "localhost:2222/test.html";
echo "*** URL ***\n";
echo $url . "\n";
echo "***********\n";
echo "** whoami *\n";
echo exec('whoami');
echo "* Output **\n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
When I execute it on the command line, it works - I get the meager results from within test.html.
When I run this script by loading up the built-in PHP server and browsing to the script, it hangs. No output to the screen, nothing written to the logs.
I read that sometimes user permissions can get in the way, so I tried doing whoami to ensure that the user that ran the built-in PHP server is the same as the one who executed the script on the command line; which they are.
safe_mode is off, disable_functions is set to nothing. I can exec other commands successfully (like the whoami).
What else should I check for? Does the built-in PHP server count as someone other user when it fulfills a request perhaps?
The PHP built-in development web server is a very simple single threaded test server. It cannot handle two requests at once. You're trying to retrieve a file from itself in a separate request, so you're running into a deadlock. The first request is waiting for the second to complete, but the second request cannot be handled while the first is still running.
Since PHP 7.4 the environment variable PHP_CLI_SERVER_WORKERS allows concurrent requests by spawning multiple PHP workers on the same port on the built-in web server. It is considered experimental, see the docs.
Using it, the PHP script can send requests to itself which is already being served, without halting.
PHP_CLI_SERVER_WORKERS=10 php -S ...
Works with Laravel as well:
PHP_CLI_SERVER_WORKERS=10 php artisan serve
I think problem in your $url. It may be look like this $url = "http://localhost:2222/test.html"; or $url = "http://localhost/test.html"; I think it's solve your problem. Thanks for your question. Best of luck.

Why is my cron job in directadmin not working?

I have the below php file which runs well in the browser AND from the command line.
<?php
$ch = curl_init ('http://www.domain.com/test_if_script_runs.php');
$output = curl_exec ($ch);
?>
The file test_if_script_runs.php only adds a number in a database so that I can see the script runs.
I've set up a cron job in directadmin. In the input fields I've only added 10 for minutes and left all other fields with a star.
So the question is, why is the cron job in directadmin not working?
UPDATE 1:
I checked that in /var/log/cron the path to the file is there. There are no error messages in that file. It seems that the cron is just working fine. However there is no output as when I run the cron from command line or from browser I checked that the file is giving the required output.
I had to put php in front of the command in order to have php process the file. I have something like the below:
php /home/admin/domain.com/public_html/script.php
This is how I do it:
cd /home/user/public_html/any/folder; /usr/local/bin/php -f file.php
This work for me:
/usr/local/bin/php /home/<USER>/domains/<DOMAIN>/public_html/script.php

PHP get what printed on command line to a variable

I have the following PHP code:
<?php
$video = "C:\Users\Administrator\myVideo\processing\video.mp4";
$cmd = 'ffmpeg -i "' . $video .'" 2>&1 | wtee buffer.txt'; // wtee is a Windows version of tee
exec($cmd);
echo($cmd);
?>
If I run aa.php, which contains the above code, it won't work.
But if I run the $cmd that is being echoed out on the command prompt directly, the file buffer.txt is created and works.
I want to get the output of this:
$cmd = 'ffmpeg -i "' . $video .'"'
Into a variable like, e.g. $output.
This code, so far, prints blank:
exec($cmd,$output,$result);
print_r($output);
Like you mentioned, that your code works directly from command line but not from PHP CLI, is most likely because of log file permissions, which means, you must create a log file with correct permissions first, and then write your output there!
For example, from command line (not PHP) make sure that you delete your log file buffer.txt and run your PHP code again. Most likely it will not work as your file doesn't exist. Remember, when you run that command from command line directly, your log file, which is buffer.txt is created with special permissions (not only read/write, but also group and owner (Linux)). When PHP creates a file, by default, it uses nobody nobody for owner/group and you already have a log file (as you ran that same command from command line), which is created by other user (I suppose administrator), as a result you can be sure that PHP will not be able to use it, just because of the wrong file permissions. Try to see what is on your current log file owner/group by executing ls -ls in Linux or DIR /Q in Windows to get the idea.
Besides everything, make sure that you're not running PHP in safe mode, as a result exec might not work as you expect it, because it's disabled if PHP is in safe mode.
shell_exec() (functional equivalent of backticks)
This function is disabled when PHP is running in safe mode.
exec()
You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have components in the path to the executable. escapeshellcmd() is executed on the argument of this function.
You can check your server's PHP settings with the phpinfo() function.
Your code should rather look like this:
exec("$cmd 2>&1", $output);
log_conversion($config['logs_path']. '/' .$video_id. '_log.txt', $cmd);
log_conversion($config['logs_path']. '/' .$video_id. '_log.txt', implode("\n", $output));
What does that mean? If you say 2>&1 then you are redirecting stderr to wherever stdout is currently redirected to. If stdout is going to the console then stderr is, too. If stdout is going to a file then stderr is as well.
Please read more about command redirections in articles Using command redirection operators for Windows or All about redirection for Linux.
Your log conversion function, could be something like this:
function log_conversion($file_path, $text)
{
$file_dir = dirname($file_path);
if( !file_exists($file_dir) || !is_dir($file_dir) || !is_writable($file_dir) )
return false;
$write_mode = 'w';
if( file_exists($file_path) && is_file($file_path) && is_writable($file_path) )
$write_mode = 'a';
$handle = fopen($file_path, $write_mode);
if( !$handle )
return false;
if( fwrite($handle, $text. "\n") == FALSE )
return false;
#fclose($handle);
}
It's very important to make sure that the log file you create is writable and has correct permissions!
I personally delete the log file in case it exists, to make sure that I have recent and reasonable log file.
I bet it will work either like this or with small tweaking!
If it doesn't work for you, please let me know and I will elaborate!
exec requires an array for the output variable.
So try:
$output = array();
exec($cmd, $output, $result);
That will give you an array where each element is a line returned by your command.

Categories