2

I edited my crontab and strangely started getting "error: bad minute". Searching around, I discovered the cause was errant control characters. I can see the character $ at the end of each line, but I can't figure out how to remove it. I am doing nothing special, just using crontab -e to edit the entry, which launches vi (vi like editor). So, how are these $ ending up in my file, and how do I remove them?

fwiw, I am using a Mac with zsh


update: added contents of the problematic crontab. See below

so, I posted an xy problem which is embarrassing. Nevertheless, my "bad minute" problem still remains. Here is the problematic crontab

HOME=/Users/punkish
APPDIR=Projects/zenodeo3
export NODE_ENV=cron
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
0 0 * * * cd $HOME/$APPDIR && bin/cron-truebug.sh
punkish
  • 253

1 Answers1

4

I can see the character $ at the end of each line, but I can't figure out how to remove it.

That's supposed to be there. The $ at the end is how cat -e indicates a line break (the LF character). "bad minute" is caused by something else.

$ man cat
 -e      Display non-printing characters (see the -v option), and display a
         dollar sign (‘$’) at the end of each line.

Here is the problematic crontab

The problem with this crontab has nothing to do with weird characters, and everything to do with entries that do not follow the crontab syntax at all. A crontab is not a shell script – each of the "jobs" contains a script, but the crontab as a whole is not, and you cannot put shell commands or constructs at the top level.

That is, you cannot put things like [ ... ] or . nvm.sh in your cronjob like that – you can do this as part of each individual job but not globally.

About the only thing that's allowed in there, besides actual job entries, is the simple ENV=value assignments like you have in lines 1–2 (which are implicitly "exported", so the export command would not be necessary anyway). It's only a coincidence that this looks like it does in scripts.

Anything else besides those assignments is assumed to be a job specification line, so the "bad minute" messages appear because the first field in lines 3–6 – which is export or [ – is indeed not a minute specification.

Your crontab would work if it looked like this:

0 0 * * * export NODE_ENV=cron NVM_DIR=$HOME/.nvm; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; cd ~/Projects/zenodeo3 && bin/cron-truebug.sh

(I omitted HOME= because cron jobs already know that, and omitted bash_completion because that's only useful in interactive shells – there's no point in loading it as part of a script. I would probably also remove the [ -s ] check; if you've set up the job you can probably just assume nvm's existence.)

If this looks too unwieldy as a cronjob, create a dedicated shell script that would set up all the necessary environment and run that as the job:

0 0 * * * ~/bin/cron.zenodeo-daily.sh

As you're on macOS, you also have the option of using launchd (Linux similarly had systemd timers).

grawity
  • 501,077