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