No, having multiple shells in SHELL
doesn't make sense, for the reasons @Stephen described in their answer. But, the SHELL
variable only controls the shell cron
uses to run the immediate command part in the crontab
line; and at least in Vixie cron, which you often have on Linux systems, SHELL
can be changed in the middle of crontab
. The Debian man page for crontab(5)
says:
The crontab file is parsed from top to bottom, so any environment settings will affect only the cron commands below them in the file.
That sentence looks like it might have been added by Debian, but it seems to work the same on the CentOS system I tried. But as noted in comments by Toby Speight, environment variable assignments in crontab
aren't a POSIX feature at all, so YMMV.
So, regardless of the cron, you should be able to do something like this:
* * * * * /path/to/somescript.py maybe
* * * * * /path/to/otherscript.pl some
* * * * * /path/to/thirdscript.sh args
where the scripts have the proper hashbang lines, e.g. #!/usr/bin/python3
, #!/usr/bin/perl
, #!/bin/bash
or whatever. SHELL
just needs to be set to something that can take /path/to/somescript.py maybe
etc. as a command and run that script with an argument. Most shells support the trivial stuff identically, so if you put the complicated stuff inside separate scripts and keep the crontab
lines simple, you can use whatever shell or scripting language in the scripts themselves.
And, if you need to use different shells in the immediate crontab commands, you can do this, at least in Vixie cron:
SHELL=/bin/bash
* * 8-14 * * if test "$(date +\%w)" = 0; then echo $BASH_VERSION > /tmp/bashtest; fi
SHELL=/usr/bin/fish
* * 8-14 * * if test (date +\%w) = 0; echo $FISH_VERSION > /tmp/fishtest; end
Both check if the day is Sunday, and print the shell version if it is, one using Bash, one using fish. (That's only an example, of course, but because of the way the cron time settings work, running on the first/second/last particular weekday of a month is one of the common cases where you might want to use shell code on the crontab command.)
Also, as an aside, you mentioned in the comments that Nu doesn't support multiline commands with \
, and was hoping you could use Bash there. Note that you can't have multiline commands in the crontab line: The command itself must be on just one line in the file, and while cron
takes a %
sign as a line break, the lines following the first are sent to the standard input of the command. (And that's why we need to escape the %
used in the format string for date
above.)
#!
line at the start of the script and the script file is executable, the shell configured incron
simply does not matter.:
separator is specific to environment variables which take lists, likePATH
and a few similar variables (NODE_PATH
,LD_LIBRARY_PATH
...), where there is a simple test to try different items of the list in order: does the file we're looking for exist in that directory or not?