2

In crontab, how do I know which shell it is using?

for example if I want to redirect output how do I know if I need to use &> or >& (bash vs csh)

3
  • 2
    Possible duplicate of How to change cron shell (sh to bash)?
    – vfbsilva
    Mar 14, 2017 at 14:28
  • 1
    Incidentally, bash supports >&, so if this is the only difference you're worried about just use that form. It also has the advantage that it's a clear error in shells that do not support it, whereas &> may simply start the process in the background with no redirection and create a blank file.
    – Random832
    Mar 14, 2017 at 15:28
  • 4
    In general, you can assume that all those system utilities use a POSIX sh, and that you cannot assume any features that are not specified in POSIX. Mar 14, 2017 at 15:51

2 Answers 2

10

From crontab(5):

Several environment variables are set up automatically by the cron(8) daemon. SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd line of the crontab´s owner. HOME and SHELL can be overridden by settings in the crontab; LOGNAME can not.

1
  • I wonder if there are cron daemons that don't allow setting environment variables in crontab..
    – ilkkachu
    Mar 14, 2017 at 16:36
2

It depends what version of cron you have, and how it is configured, but usually it is /bin/sh. Often that is a symlink to something else though, but that is easy to find as you can simply run ls -l /bin/sh.

You could add a cron entry like:

* *    * * *    ps -p $$ > /tmp/shelltest

or (if editing /etc/crontab instead of adding an entry to a per-user crontab as done via crontab -e):

* *    * * *    username    ps -p $$ > /tmp/shelltest

which will tell you via output to /tmp/shelltest the filename of the shell. If your cron is properly setup to mail output to you then you can skip the >/tmp/shelltest to get the information by mail instead of it being dropped into a file.

To be a bit more trixy something like:

* *    * * *    ls -l /proc/`ps -p $$ | tail -n 1 | xargs | cut -f 1 -d \ `/exe > /tmp/shelltest

should tell you the exact file used. On a typical Debian system this will result in something like:

lrwxrwxrwx 1 dspillett dspillett 0 Mar 14 16:17 /proc/1356/exe -> /bin/dash

showing that cron is using dash as the default shell in this instance.

To break that command down:

  • ps -p $$ outputs details of the current process (well, ps's parent process) which will be the shell in this case.
  • tail -n 1 strips away the header row that ps includes
  • piping through xargs is a trick to trim off leading spaces from the line
  • the cut invocation takes the first field from the like where the deliter is spaces (it is absolutely vital that you include the space between the \ and the backtick)
  • wrapping that in backticks includes the output (which should be a process ID) in the outer command line which becomes...
  • ls -l /proc/9999/exe where "9999" is the process ID read from ps which lists the file used to create the process because in the '/proc' filesystem /proc/<pid>/exe is a link to the executable of the process identified by <pid>.
  • (there may be a more concise way to do the same thing, that was typed from memory, suggestions welcome via comments!)
1
  • ps -p $$ --no-headers -o '%P' shows the parent ID of the process whose value is in $$ Mar 16, 2017 at 23:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .