(I have already read How can I test a new cron script ?.)
I have a specific problem (cron job doesn't appear to run, or run properly), but the issue is general: I'd like to debug scripts that are cronned. I am aware that I can set up a * * * * * crontab line, but that is not a fully satisfactory solution. I would like to be able to run a cron job from the command line as if cron were running it (same user, same environment variables, etc.). Is there a way to do this? Having to wait 60 seconds to test script changes is not practical.
Here's what I did, and it seems to work in this situation. At least, it shows me an error, whereas running from the command line as the user doesn't show the error.
Step 1: I put this line temporarily in the user's crontab:
then took it out once the file was written.
Step 2: Made myself a little run-as-cron bash script containing:
So then, as the user in question, I was able to
This solution could obviously be expanded to make use of sudo or such for more flexibility.
Hope this helps others.
I present a solution based on Pistos answer, but without the flaws.
Add the following line to the crontab, e.g. using
crontab -e
Create a shell script which executes a command in the same environment as cron jobs run:
Use:
e.g.
Note that the second argument needs to be quoted if it requires an argument. The first line of the script loads a POSIX shell as interpreter. The second line sources the cron environment file. This is required to load the correct shell, which is stored in the environment variable
SHELL
. Then it loads an empty environment (to prevent leaking of environment variables into the new shell), launches the same shell which is used for cronjobs and loads the cron environment variables. Finally the command is executed.As crontab don't do the job, you'll to manipulate it's content :
What it does :
By default with most default cron daemons that I have seen, there is simply no way of telling cron to run right here right now. If you're using anacron, it may be possible I think to run a separate instance in the foreground.
If your scripts aren't running properly then you are not taking into account that
From crontab(5):
In general PATH is the biggest problem, so you need to:
If you need to run the script as another user without a shell (e.g. www-data), use sudo:
The first thing to test before all of that, of course, is that your script actually does what it is supposed to do from the command line. If you can't run it from the command line, it will obviously not work from with cron.
Marco's script didn't work for me for some reason. I didn't have time to debug, so I wrote a Python script which does the same thing. It's longer, but: first, it works for me, and second, I find it easier to understand. Change "/tmp/cron-env" to where you saved your environment. Here it is:
Marco's solution didn't work for me but Noam's python script worked. Here is slight modification to Marco's script that made it work for me:
The added
set -a
export variables defined in script $1 and made it available to command $2p.s. Noam's python worked because it 'exported' environment to the child process.
I noodled on Marco's answer. Code is shown below, but I will maintain this script here.
Given this crontab:
Sample usage session:
This is
cronTest2
, which needs to be properly invoked to set up the environment variables the same way as cron does:cronTest
runscronTest2
with the proper environment variables set:In most crontabs like e.g. vixie-cron you can place variables in the crontab itself like this and then use /usr/bin/env to check if it worked. This way you can make your script work in crontab once you found out whats wrong with the run-as-cron script.
If it's a shell script, this should get you most of the way:
It'll definitely highlight some problems, if not everything.
Well, the user is the same as the one you put in the crontab entry (or whose crontab you put it into, alternately), so that's a no-brainer.
crontab
(5) should give you the list of environment variables set, there's only a few.