This is on a CentOS machine. I'm trying to run a script as user nobody (or as a user with minimal permissions) at a certain time every day. Here is nobody:

[root@CentOS % ~] grep "^nobody" /etc/passwd  

here's what I've tried in root's crontab:

setting the Environment variable SUDO_USER=nobody
15 17 * * * sudo -u nobody /bin/bash /usr/local/bin/bashscript.sh
15 17 * * * su -c /usr/local/bin/bashscript.sh nobody

I'd like to keep the crontab entry in root's crontab if at all possible. I'd also prefer not fooling with user nobody's account, as I don't want to break anything else that might rely on those settings. I'm not adverse to creating another non-privileged account and giving them a real shell if that's the sticking point.

I'll also admit to being a bit perplexed. I would assume this would be an everyday issue, except my brown belt in google-fu isn't helping much.

  • How do you determine whether the script is running under nobody or some other user? Both ways work for me. – whitequark Jan 21 '10 at 23:06
  • @whitequark - the script creates an output file if it runs. It creates it in /tmp (where I presume user "nobody" has privileges. – pica Jan 21 '10 at 23:17
  • also, there's no /etc/cron.d/crontab.allow, or /etc/cron.d/crontab.deny on the system. – pica Jan 21 '10 at 23:19
  • Did you tried running it with su nobody manually? Did you checked cron logs (syslog output maybe) after it was supposed to be run? – whitequark Jan 21 '10 at 23:50
  • @whitequark - cron has logs? let me look Jan 21 18:25:01 uname -n crond[7776]: (root) CMD (su -c /usr/local/bin/bashscript.sh nobody) so root is in those parentheses, so that's who ran the script. but running that on the command line gets me "This account is currently not available." b/c /etc/passwd is set to nologin – pica Jan 22 '10 at 0:12

I'm guessing you are posting the contents of crontab -e or crontab -l?

This is the crontab file beloning to user "root", and that file does not support specifying a user to run the command as (as it's generally a file used for scheduling personal jobs).
Look at /etc/crontab instead which is the system-wide crontab and has an additional field: the user field. Try adding a line like this to /etc/crontab:

15 17 * * * nobody /usr/local/bin/bashscript.sh
  • Existing practice everywhere I've seen is to do the day to day maintenance jobs in root's crontab. I suppose that's a bad practice because there is a field to put in the user that the cronjob should be run under. I've never even heard of /etc/crontab before. This makes for a better answer than my workaround. – pica Jan 22 '10 at 0:46
  • 3
    actually /etc/cron.d/ seems to be the preferred location over /etc/crontab . Ubuntu documentation says /etc/crontab could be affected by updates. – pica Jan 22 '10 at 1:15

su --shell=/bin/bash --session-command="/path/to/command -argument=something" username &

Works for me and doesn't throw the "This account is currently not available." error even when the user doesn't have a valid login shell


Actually clawspoon lead me to the answer, but let me create my own, more complete answer so it can float to the top.

I don't know how common it is, but some online Ubuntu documentation says that /etc/crontab can be overwritten upon upgrade, and the preferred solution is to create a file called /etc/cron.d/anything (where anything can be, well, anything. Any filename)

I've created a file called /etc/cron.d/nobody and I'm putting the scripts to run as a non-privileged user. example lines:

# run the following every day at 01:02 AM
02 01 *  *  *  nobody /usr/local/bin/script-to-run-as-nobody.sh

I've put a comment in root's crontab for others to follow, as day to day crontab jobs are currently all being run from there. Not exactly the best practice.

Also, for testing purposes, I need to first run the job via the command line. since I have sudo privlages, I use:

$ sudo -u root sudo -u nobody /usr/local/bin/script-to-run-as-nobody.sh

If that script needs to output to /dev/stderr or /dev/stdout, then do the following:

$ chmod o+w /dev/ttyp1

and do a:

$ chmod o-w /dev/ttyp1 

when you are finished testing to prevent just anyone from sending junk to your terminal screen. (the actual terminal you are using may differ from /dev/tty1, so do a $ ls -ltr /dev/tty*|grep username to find out which one is yours).


Workaround instead of a real answer:

You can add a comment to your crontab

**#see crontab -u nobody -l for something that runs everyday at 1:15 AM**

and then just add an entry to the user "nobody" crontab. I used:

**15 1 *  *  *   /usr/local/bin/script.sh #comment**

workaround #2

you can create an unprivileged user that does have a login shell in /etc/passwd

say, create a user called "somebody", deny them sudo, but give them a shell

Then the following should work in root's crontab:

15 1  *  *  *  su -c /usr/local/bin/bashscript.sh somebody

I like the /etc/crontab answer by clawspoon better though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy