Here is how I did it to simulate the cron execution of a script I've created years ago but which started failing recently.
I created a script called
env -0 > /tmp/$base.$$.dump
This dumps all environment variables into a file in
/tmp/. Then I modified my crontab to add:
*/1 * * * * [path to newly created script]
This makes the script run every minute. So after a minute, I got a dump of the environment seen by tasks run from cron. If the crontab line is left to run more than a minute, it creates a bunch of identical files with names differing only in the pid part of the file name (
$$). No biggie. I could have coded for this eventuality so as to get just one file but the main principle here is "good enough", and I might want to use
dumpenv in other contexts where multiple dumps are useful. At any rate, it is advisable to remove the crontab line that was added so as to avoid populating
/tmp with lots of junk.
Then I created an additional file which I called
/tmp/command which contained the command I wanted to execute, on a single line terminated by a null character. The null character is necessary.
Then I issued:
cat [path to dumpfile crated earlier] /tmp/command | xargs -0 -x env -i
And this replicated the fault I saw when my command is executed from cron. What
xargs does is build an command of the form:
env -i [list of environment variables] [command to execute]
and executes it. The list of environment variables comes from the dump file. The command that
env executes comes from the
-0 arguments to
xargs and the required null character I mention above is to prevent environment mangling while variables are being passed around. In cases where the environment contains no environment variable with a newline in it,
-0 could conceivably be omitted from the invocation of
env in the
dumpenv script and from the
xargs command, and the
/tmp/command file would not require a null character as a line terminator.
I do no explicit redirection of stdin to /dev/null because xargs does it for me. I also do not care about redirecting stdout/stderr, and I do not want to receive an email if the command fails. For cases where these features are desired, Gilles' answer provides the means to do it.