Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a cron job that is running a script. When I run the script via an interactive shell (ssh'ed to bash) it works fine. When the script runs by itself via cron it fails.

My guess is that it is using some of the environmental variables that are set in the interactive shell. I'm going to troubleshoot the script and try and remove these.

After I make changes, I know I could queue up the script in cron to have it run as it would normally, but is there a way I can run the script from the command line, but tell it to run as it would from from - i.e. in a non-interactive environment?

share|improve this question
    
Related and thus possibly helpful: "How to get a clean environment in a ksh shell?" see especially @Gilles answer regarding unset. –  sr_ Nov 3 '11 at 13:16
1  
From @sr_'s link, I looked up env, and you might want to try env -i ./my-script.sh. Also, are you getting an error message? –  Kevin Nov 3 '11 at 14:12
    
What cron implementation are you using? –  rozcietrzewiacz Nov 3 '11 at 17:10
    
@kevin - i'll upvote that if you answer with it. –  cwd Dec 20 '11 at 22:46

5 Answers 5

up vote 4 down vote accepted

The main differences between running a command from cron and running on the command line are:

  • cron is probably using a different shell (generally /bin/sh);
  • cron is definitely running in a small environment (which ones depends on the cron implementation, so check the cron(8) or crontab(5) man page; generally there's just HOME, perhaps SHELL, perhaps LOGNAME, perhaps USER, and a small PATH);
  • cron treats the % character specially (it is turned into a newline);
  • cron jobs run without a terminal or graphical environment.

The following invocation will run the shell snippet pretty much as if it was invoked from cron. I assume the snippet doesn't contain the characters ' or %.

env - HOME="$HOME" USER="$USER" PATH=/usr/bin:/bin /bin/sh -c 'shell snippet' </dev/null >job.log 2>&1

See also executing a sh script from the cron, which might help solve your problem.

share|improve this answer
    
Hi @Giles - just thought of something - would running a script like sudo -u user /path/to/script also be a way to run it without any variables set? –  cwd Sep 17 '12 at 19:57
    
@cwd No, usually not. sudo clears some variables and sets others to a known value, but that depends on how it's configured. It is often configured to retain locale settings and TERM, for example. –  Gilles Sep 17 '12 at 20:00

From @sr_'s link (How to get a clean environment in a ksh shell?), I looked up env, and you might want to try this:

env -i ./my-script.sh
share|improve this answer
    
This worked well for me although @Gilles answer is also really good. –  cwd Dec 20 '11 at 23:29
    
@cwd: Doesn't work for me: echo -e '#!/bin/bash -i\necho interactive $-' > ~/test.sh && chmod +x ~/test.sh && env -i ~/test.sh outputs interactive himB. –  Alix Axel Nov 18 '12 at 3:14

I would suggest you use absolute paths for your scripts when putting it in cron and using elsewhere and for any and all linux commands used in it, better declare them as variables and use it thereof!

share|improve this answer
    
yes. but of course. –  cwd Nov 3 '11 at 15:44

Cron doesn't necessarily use the same shell you are using. check:

cat /etc/crontab |grep SHELL

To determine the shell and attempt execution of your script there - does it work? This is a common cause of issues for many people adding scripts to cron.

If this is the problem - you can add "bash" to the beginning of your script in cron to force this script to execute in bash. If this does not solve the issue, let me know and I'll dig a little deeper.

share|improve this answer

If you'd like to ignore some interactive questions provided by some script, you can try:

yes | your_command

Or yes "n" if you'd like to No all the questions.

Command:

yes -- be repetitively affirmative yes outputs expletive, or, by default, 'y', forever.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.