LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Running a cron as root (https://www.linuxquestions.org/questions/linux-newbie-8/running-a-cron-as-root-455397/)

koobi 06-16-2006 08:57 AM

Running a cron as root
 
this is the contents of my crontab:
Code:

crontab -l
@reboot gnome-clipboard-daemon

* * * * * sudo sh /etc/ppp/ip-up.d/dyndns_update.sh >> /home/USER/Desktop/dyndns

as you can see, i'm trying to run a certain file as root and output it to a file named dyndns on my Desktop.
the thing is, it won't run...i suspect it's because it's set to run as root (via sudo).

how would i add my root password so that the cron will use that an carry on? running this file requires root permissions.


thanks for your time.

kencaz 06-16-2006 09:15 AM

why not just change the ownership of dyndns_update.sh... Then sudo would not be needed.

KC

MensaWater 06-16-2006 09:17 AM

In the root crontab you don't need "sudo" to run as root. The root crontab itself runs as root. Also "sudo" is interactive (requires user to input their password) so would not run in the background anyway. To switch users you use "su" rather than "sudo".

Restated: Become root first THEN do your "crontab -e" to add the job to your root's crontab file.

koobi 06-16-2006 09:45 AM

Quote:

Originally Posted by kencaz
why not just change the ownership of dyndns_update.sh... Then sudo would not be needed.

KC

well i have to run that script as root because it uses something that requires root permissions. thanks though.


jlightner,
i did this:
Code:

sudo crontab -e
then added this:
Code:

* * * * * sh /etc/ppp/ip-up.d/dyndns_update.sh >> /home/USER/Desktop/dyndns.root
i added a line break underneath it too.


it ran once at 20:36 (right after i created the cron) but that's it:
Code:

ls -lah | grep dydns
-rw-r--r--  1 root  root    0 2006-06-16 20:36 dyndns.root


i don't have to source the crontab right? is my crontab wrong? i want this cron to happen every minute, on the minute.


i just tried this as well:
Code:

*/1 * * * * sh /etc/ppp/ip-up.d/dyndns_update.sh >> /home/USER/Desktop/dyndns.root
but had no luck.

thanks for your time.

MensaWater 06-16-2006 11:05 AM

Quote:

Originally Posted by kencaz
why not just change the ownership of dyndns_update.sh... Then sudo would not be needed.

KC

That would only be true if you set it with the SUID bit turned on. Not a good idea in general and especially for shell scripts. SUID has its uses but it should be used sparingly.

MensaWater 06-16-2006 11:15 AM

Not sure why it wouldn't work unless it is finding the previous invocation already running and you have it testing for that. It would depend a lot on what is in the script itself. (You really don't want multiple copies of the same shell script running at the same time - they contend for the same resources and will eat up your CPU).

I would suggest however that instead of doing:
Code:

sh /etc/ppp/ip-up.d/dyndns_update.sh >> /home/USER/Desktop/dyndns.root
You do:
Code:

/etc/ppp/ip-up.d/dyndns_update.sh >> /home/USER/Desktop/dyndns.root 2>&1
Within dyndns_update.sh make the first line:
Code:

#!/bin/sh
The first change gets rid of the extraneous shell with cron itself which may confuse things a bit. It also redirects standard error (stderr) to standard out (stdout). As you had it only stdout would go to the file dyndns.root.

The second change insures your commands within the script are executed with /bin/sh. (This is called the interpreter and is special syntax.) This way even if someone running another shell (ksh, csh, zsh) runs the script it will behave the same way every time because it runs as sh.

Finally remember that even if your script is successful from command line it may fail in cron. This is because at command line the script inherits the user's environment ($PATH, $HOME, $DISPLAY, etc...) but cron runs a minimal environment not a user's environment. Therefore you must insure the script (dyndns_update.sh) contains all the environment variables you'll need (especially $PATH) so it can find what its looking for when it runs.

koobi 06-16-2006 03:20 PM

thanks jlightner.

Code:

cat /etc/ppp/ip-up.d/dyndns_update.sh
 #!/bin/sh

# the details below were edited to make it safe to post it here
# the version on my PC has the right details
 USERNAME=user
 PASSWORD=pass
 HOSTNAME=host.dyndns.org

 cd /root/
 if [ -f /root/ipcheck.dat ]; then
  ipcheck -r checkip.dyndns.org:8245 $USERNAME $PASSWORD $HOSTNAME
 else
  ipcheck --makedat -r checkip.dyndns.org:8245 $USERNAME $PASSWORD $HOSTNAME
 fi

and i took that from here: How to assign Hostname to local machine with dynamic IP using free DynDNS service

so as you can see, i do have the shebang line.
and in any case, root and all other users run on /bin/bash on this machine.



do i have to define $PATH in my script?

i did this:
Code:

* * * * * echo $PATH > /home/koobi/Desktop/path

Code:

cat path
/usr/bin:/bin

$HOME shows the expected results but $DISPLAY is empty but this is a cron and it doesn't need that does it?






and i just tried this:
Code:

/etc/ppp/ip-up.d/dyndns_update.sh >> /home/USER/Desktop/dyndns.root 2>&1
and that seemed to work fine.

if you don't mind, could you please explain the 2>&1 in more detail? or at least tell me what it's called so i could look it up on google. i know you mentioned stderr and stdout but is there a name for them together in this context?

MensaWater 06-17-2006 09:38 AM

OBSERVATION:
It appear from the way your post looks that you have a space before what you call the shebang line (actually known as the interpreter line). The special syntax requires the # to be the first position on the line so if there is actually a space before it you should remove it.
(# in any other location is a "comment" identifier meaning do NOT process what follows the #).

ANSWER TO PATH QUESTION:
Nice trick on figuring out which PATH cron uses there. You are only calling one external command in your script which is ipcheck. (Not counting the interpreter line which has full path to sh in it already.)

Since you see cron uses /bin and /usr/bin to find files the answer to whether you need to define PATH depends on whether the external commands you're calling reside in the PATH you already have. Type "which ipcheck". If it is in /bin or /usr/bin then you don't need to define it (though I likely would anyway). You don't actually have to have the PATH statement though. If you wer calling multiple external commands you might want the PATH statement just to avoid a lot of typing. An alternate way to do it is simply to use the fully qualified path name. Finally you can simply create a variable for the fully qualified path name of the executable which is what I usually do in cron and init scripts.

Example - assume the command ipchceck is in the directory /usr/local/ipchceck/bin:

Define PATH:
[CODE] export PATH=/bin:/usr/bin:/usr/local/ipcheck/bin [CODE]

-or-

Use fully qualified path name each line you want to use ipcheck:
[CODE]if [ -f /root/ipcheck.dat ]; then
/usr/local/ipcheck/bin/ipcheck -r checkip.dyndns.org:8245 $USERNAME $PASSWORD $HOSTNAME
else
/usr/local/ipcheck/bin/ipcheck --makedat -r checkip.dyndns.org:8245 $USERNAME $PASSWORD $HOSTNAME
fi[CODE]

-or-

Define a variable for the executable:
[CODE]export IPCHECK=/usr/local/ipcheck/bin/ipcheck
if [ -f /root/ipcheck.dat ]; then
$IPCHECK -r checkip.dyndns.org:8245 $USERNAME $PASSWORD $HOSTNAME
else
$IPCHECK --makedat -r checkip.dyndns.org:8245 $USERNAME $PASSWORD $HOSTNAME
fi[CODE]

ANSWER TO DISPLAY QUESTION
No. I used DISPLAY only as an example of common variables. In a recent thread I did see where a user found a use for having cron have that variable but in general cron stuff is backgrounded so wouldn't need DISPLAY.

ANSWER TO 2>&1
Actually I had recently given an explanation of redirection and the tee command in another thread. Hopefully it will explain the 2>&1 to you in more detail. Have a look and if not let me know:
http://www.linuxquestions.org/questions/showthread.php?p=2288544#post2288544


All times are GMT -5. The time now is 12:34 PM.