Reputation: 3171
I have several scripts scheduled to run in my crontab, but can only see them as root (or using sudo). I need to have a PHP script (which is being run as nginx) be able to add a new line to the crontab file. To do this I created a shell script (owned by root) and gave the nginx
user permission to sudo
it via the /etc/sudoers
file.
The last line of the /etc/sudoers
file:
nginx ALL=NOPASSWD: /etc/nginx/addcron.sh
The PHP call to execute the script:
chdir("/etc/nginx/");
echo exec("2>&1 ./addcron.sh $custname", $output);
echo "<pre>".print_r($output, true)."</pre>";
My current crontab:
[ec2-user@ip-172-31-xx-xxx nginx]$ sudo crontab -l
* * * * * env > /tmp/env.output
* * * * * /usr/bin/php -f /var/www/html/example/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/demo/cron/cron.php
0 23 * * * rm /tmp/cachegrind.out.*
Meta information about my addcron.sh
file:
[ec2-user@ip-172-31-xx-xxx nginx]$ pwd
/etc/nginx
[ec2-user@ip-172-31-xx-xxx nginx]$ ls -al addcron.sh
-rwxr-xr-x 1 root root 129 Nov 24 22:16 addcron.sh
The contents of addcron.sh
:
#!/bin/bash
custname="$1"
(crontab -l; echo \"* * * * * /usr/bin/php -f /var/www/html/$custname/cron/cron.php\" ) | crontab -
When I try to run this though, I get the following error:
errors in crontab file, can't install.
Array
(
[0] => "-":102: bad minute
[1] => errors in crontab file, can't install.
)
It seems like it doesn't like the -
mark in addcron.sh
, but my Google searches suggest this is correct. Also, I have tried adding sudo
to the PHP's exec
command, but then I just get the following error:
sorry, you must have a tty to run sudo
What am I doing wrong or missing, and why?
Upvotes: 0
Views: 231
Reputation: 605
I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
$custname= "someone";
$strCmd = "echo \"* * * * * /usr/bin/php -f /var/www/html/".$custname."\" >> /cron/cron.php";
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd($strCmd);
//assuming your distribution reloads / restarts using 'service'
$return2 = $shell->exeCmd('service crond restart');
this will append your line to the cron file.
Upvotes: 0
Reputation: 39824
Side note: running cron jobs unrelated to the system admin under the root
's account is a BAD IDEA from the security prospective. Install your crons under the nginx
user.
The issue is caused by the escaping of the quotes in your bash script (which you can check directly in bash, piece by piece, btw):
> (crontab -l; echo \"* * * * * /usr/bin/php -f /var/www/html/$custname/cron/cron.php\" )
no crontab for username
"* ... <all kinds of filenames in here> ... /usr/bin/php -f /var/www/html/the_customer/cron/cron.php"
Without the quote escaping things work a bit better:
> (crontab -l; echo "* * * * * /usr/bin/php -f /var/www/html/$custname/cron/cron.php" )
no crontab for username
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
You might want to add some protection against duplicating the entries, here's how crontab looks after a few invocations:
> crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:10 2015)
# (Cronie version 4.2)
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:09 2015)
# (Cronie version 4.2)
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:09 2015)
# (Cronie version 4.2)
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:08 2015)
# (Cronie version 4.2)
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:07 2015)
# (Cronie version 4.2)
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
Upvotes: 1