How to simulate the environment cron executes a script with?
Solution 1:
Add this to your crontab (temporarily):
* * * * * env > ~/cronenv
After it runs, do this:
env - `cat ~/cronenv` /bin/sh
This assumes that your cron runs /bin/sh, which is the default regardless of the user's default shell.
Footnote: if env
contains more advanced config, eg PS1=$(__git_ps1 " (%s)")$
, it will error cryptically env: ": No such file or directory
.
Solution 2:
Cron provides only this environment by default :
-
HOME
user's home directory -
LOGNAME
user's login PATH=/usr/bin:/usr/sbin
SHELL=/usr/bin/sh
If you need more you can source a script where you define your environment before the scheduling table in the crontab.
Solution 3:
Couple of approaches:
-
Export cron env and source it:
Add
* * * * * env > ~/cronenv
to your crontab, let it run once, turn it back off, then run
env - `cat ~/cronenv` /bin/sh
And you are now inside a
sh
session which has cron's environment -
Bring your environment to cron
You could skip above exercise and just do a
. ~/.profile
in front of your cron job, e.g.* * * * * . ~/.profile; your_command
-
Use screen
Above two solutions still fail in that they provide an environment connected to a running X session, with access to
dbus
etc. For example, on Ubuntu,nmcli
(Network Manager) will work in above two approaches, but still fail in cron.* * * * * /usr/bin/screen -dm
Add above line to cron, let it run once, turn it back off. Connect to your screen session (screen -r). If you are checking the screen session has been created (with
ps
) be aware that they are sometimes in capitals (e.g.ps | grep SCREEN
)Now even
nmcli
and similar will fail.