Running bash scripts from cron
cron
does not run bash
by default. Nor does it run the same sh
that you'd get as a user somehow, at least on Ubuntu 18.
Here's an experiment I did. I ran this script from a cron job:
#!/bin/bash
catfile=$(which cat)
echo "Cat file: $catfile"
The email reporting the cron job run contained this:
Cat file:
That's it. It could not find cat
.
I logged in to the server and ran sh
. From sh
, I ran the same script. Here's the output:
Cat file: /bin/cat
But here's a twist. From within sh
, I ran echo $SHELL
and got:
/bin/bash
So, just typing sh
doesn't take you to that shell.
$ file -h /bin/sh
/bin/sh: symbolic link to dash
?! Because it's a symlink to dash! It's a nicer sh
.
When I do what I should have done in the first place and run this script via cron
#!/bin/bash
echo "$SHELL"
I get:
/bin/sh
So, it is running sh. What's the difference, then? Well, echo $PATH
in sh
lists /bin
. Which is identical to what I have in bash
.
When cron runs a script that echoes the $PATH, I get:
shell: /bin/sh
path: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Cat file: /bin/cat
Whaaaat. Why do I get all of these things resolved paths now?
If I comment out the $PATH echoing line from my script and run it with cron, I still get the resolved paths.
I guess I changed something that I didn't notice? But sometimes that's just part of the insanity of debugging. Update: Actually, I added /bin
to the PATH at the top of the cron file without remembering!
#shell #mystery #unix #bash #cron