This question already has an answer here:

If I create a cronjob as:

* * * * * /root/runfile

And I put the contents of /root/runfile as:

printenv >> /root/printenv

The contents that appear in /root/printenv are:


Note that it says "SHELL=/bin/sh" however my script has a shebang as #!/bin/bash. But printenv (env, set) are all reporting /bin/sh as the shell.

However if I run those commands inside runfile it successfully reports /bin/bash:

ps -p$$ -ocmd= >> /root/printenv
readlink /proc/$$/exe >> /root/printenv

It proves I'm in an actual /bin/bash shell:


As I write this question, I'm realizing that perhaps the reason is that it's inheriting the previous SHELL environment variable, and that never changes which is why its contents are still from the cron calling process which is /bin/sh. That explanation is confirmed in the second linked question by Gilles.

marked as duplicate by Thomas Dickey, Tim Kennedy, Gilles bash Jan 24 '17 at 23:50

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    @ThomasDickey: I'm not looking for a fix, I'm asking for the theory behind why it behaves this way. – Wadih M. Jan 24 '17 at 2:01
  • @TimKennedy: The linked answers explain the first part of the question, but not the second part on why I'm never able to prove the interpreter is /bin/bash when I run /bin/bash -c "command" in crontab directly. – Wadih M. Jan 24 '17 at 2:27
  • Because the shebang line in a script doesn't change the SHELL environment variable. They are two different pieces of data. The shell is an environment setting that is not modified by the interpreter running a script. Cron by default uses /bin/sh as it's shell. You can however specify a different shell in your crontab file, SHELL=/bin/bash on it's own line. – Tim Kennedy Jan 24 '17 at 2:45
  • @TimKennedy: I'm aware of that, I've read it many times already and I know it. I've updated my question to the following: in the direct cronjob of * * * * * /bin/bash -c "command" how can I prove that it's being interpreted by /bin/bash ? – Wadih M. Jan 24 '17 at 2:52
  • The only way I can think of would be to catch the output of ps -h -o comm -p $$ from inside the script. That should return the process name of the script interpreter. It would be nice if there was an INTERPRETER environment variable that would get set, wouldn't it? – Tim Kennedy Jan 24 '17 at 3:00

Browse other questions tagged or ask your own question.