Search code examples
pythonbashshellcronanaconda

Running a bash script from a cronjob fails with "No such file or directory"


I'm trying to run the following bash script which runs a Python program after activating a conda environment.

send.bash

#!/bin/bash
source activate manage_oam_users
python ~/path/to/script/send.py
source deactivate

crontab

30 * * * * source /path/to/script/send.bash

I get the following error from cron, although running source send.bash works perfectly. I've also tried using bash send.bash which works fine when run manually, but results in the same error when run from cron.

/path/to/script/send.bash: line 2: activate: No such file or directory

Solution

  • activate and deactivate are probably scripts located somewhere an entry in your $PATH variable points to. Usually, software installed locally for one user adds statements to your .profile file or .bashrc that extend your $PATH variable so that you can use the software's scripts without using full paths.

    While your bash loads .profile and .bashrc automatically, CRON won't do that. There are at least two solutions for this.

    A) Full Paths everywhere

    Either you use full paths in the script executed by your CRON job, like this:

    #!/bin/bash
    source /path/to/activate manage_oam_users
    python $HOME/path/to/script/send.py
    source /path/to/deactivate
    

    Also use $HOME instead of ~. You can find out the full paths using which activate and which deactivate in your shell.

    B) Source .profile or .bashrc

    Alternatively you can source your .profile (or .bashrc; you will have to look which file extends your $PATH variable with the anaconda directories) in your CRON tab:

    30 * * * * source $HOME/.profile; source /path/to/script/send.bash
    

    Extra: What does source mean?

    source is a Unix command that evaluates the file following the command, as a list of commands, executed in the current context.

    from Wikipedia, the something something great encyclopaedia

    A commonly used alias for the source command is a single dot (. /path/to/script).

    A related, but more generic question can be found on the UNIX and Linux Stack Exchange.