2

I have a cron job set to execute a shell script telling the server to run a single ruby command (jekyll build --source /path/to/source/dir --destination /path/to/dest/dir) 2 minutes past every hour. The script executes just fine when I run it via the terminal, but cron doesn't seem to fire it. I know cron's environment isn't the same as the user's and I've set its source path to my .bash_profile, where the user ruby environment is defined, as per advice elsewhere. I'm rather at a loss now.

The crontab entry looks like this:

2 * * * * . $HOME/.bash_profile ~/jek.sh

FWIW, the relevant section of .bash_profile, set up automatically when RVM was installed (on shared hosting, with somewhat outdated ruby no less, getting Jekyll up and running without being able to write to the server's own ruby directory means using RVM; this seems to work absolutely fine), is:

PATH=$PATH:$HOME/bin

export PATH

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

Am I calling my user profile for use in the cron environment wrongly? Am I missing something glaringly obvious in the syntax? Any help would be much appreciated.

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
John R
  • 45
  • 1
  • 5

3 Answers3

3

What do you think $HOME will evaluate to in cron's environment?

Since you are using rvm. This is the correct way to run cron jobs

Litmus
  • 10,558
  • 6
  • 29
  • 44
  • Handy link, thanks. Unfortunately, while it's useful to be able to check the path to RVM ruby is right and called OK, using a script formatted according to the suggestions there doesn't seem to help. – John R Oct 04 '13 at 20:21
  • The method shown under [Loading RVM environment files in shell scripts](https://rvm.io/integration/cron#loading-rvm-environment-files-in-shell-scripts) worked perfectly in my case (along with the necessary additions to PATH in the crontab file). – yukondude Mar 16 '17 at 15:41
1

You may need to use absolute paths because cron can be very picky.

Try this after 'crontab -e':

2 * * * * /bin/bash /home/username/jek.sh

If you want to string commands together, use && between each:

2 * * * * /bin/bash /home/user_name/.bash_profile && /bin/bash /home/username/jek.sh

As a note, besides /bin/ you can find many commands in /usr/bin. To find the absolute location of a command, use 'which'. For example, :

user@computer:~$ which bash
 /bin/bash

Finally, you can probably use cron to run the ruby script directly, with an absolute path to jekyll, and probably after && in order to set up the environment first.

philshem
  • 24,761
  • 8
  • 61
  • 127
  • As I've noted below, this looks really sensible - thanks - but whichever way I try it the script simply doesn't seem to execute still. – John R Oct 04 '13 at 20:27
1

In your question, the cron you are running goes like

2 * * * * . $HOME/.bash_profile ~/jek.sh

There are multiple things you need to correct/verify with this entry

  1. Check that file permissions for both is 777 or 775 (rwx). If not, then change the file permission using chmod 777 ~/jek.sh
  2. Check that each of them define in their shebang line which language script they are (#!/usr/local/env sh)
  3. Separate the two scripts by an && or ; so that both of them are run properly. Currently, the second script's name will be treated as a parameter for the first.
  4. There is a . after the 2 * * * * part. I am not sure why you added it - it has to be removed.


In case @psny's answer doesn't work for you, try exporting your path variable in your cron entry. After that, the whole thing should work properly. Steps

1) Find the value of $PATH

echo $PATH #Lets call the string :some/path/:another/path

2) Manually set the path in your crontab entry

2 * * * * export PATH=:some/path/:another/path && /bin/bash /home/username/jek.sh
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • Permissions are OK, and the shebang seems fine. The `.` was, IIRC, a shorthand mark for source (from memory). Trying it in the crontab with the full path (or with @psny's suggestions) *still* doesn't let the thing run, though. It must be an environment thing, I assume, because the script executes just fine by hand. What it is that cron doesn't like is mystifying me. – John R Oct 04 '13 at 20:23
  • @JohnR Do you export some jekyll related environment variables in your .bash_profile? If so, try exporting them as well in the crontab entry. Once the entry works, you can move the exact details to your shell file. – Anshul Goyal Oct 05 '13 at 01:56
  • @JohnR Regarding `The . was a shorthand mark for source (from memory)` - Is this representing the current working directory, or is it an alias. If first, you are using it incorrectly (which is why I suggesting removing it), if second, you need to run the corresponding command for the alias in your shell script. Also, take care of separating the shell commands using `&&` or `;`. – Anshul Goyal Oct 05 '13 at 02:22
  • Yeah, I took the `.` out and avoided using $HOME. This morning I finally got an email notification of the cron job running using the full path in the crontab (why it's taken this long, I don't know; the time setting is right). It looks like it works with the full path, but Jekyll's returning warnings caused by imported posts containing things that look like markdown tags (non-critical - the `build` command is happy to continue through them in terminal). Presumably cron's tripping up on these... – John R Oct 05 '13 at 06:32
  • So it looks like the full path was the answer - I just need to clean up the little glitches leftover from import before cron's happy. Thanks, to everyone, for your help! – John R Oct 05 '13 at 06:34