Score:1

How to have an environment variable with quotes in crontab?

lk flag

I have a minimum example of my problem, which is trying to install a crontab that looks like this:

FOO="foo\"bar\"bin"

0 0 1 * * ls

by running crontab crontab (I have it in a file name crontab). It fails with this error:

% crontab crontab
"crontab":0: bad minute
crontab: errors in crontab file, can't install

It's the escaped quote, \", causing the problem.

How do I escape quotes in crontab's environment variables.

To add a bit more context, I'm not just writing variables in a manually written crontab. This crontab is generated by whenever (a Ruby gem), it has about 70 entries in them, and it picks up all environment variables and puts them as variables in the crontab so all credentials are available to the scripts. The problem is that recently I added a complex one that has quotes in it, and that broke this system.

In case you are curious, the Ruby code that generates the variables is:

ENV.each do |key, value|
  env key.to_sym, value.inspect
end
Score:1
in flag

The good practice for cron is:

  1. Create script to run the commands
  2. Set variables in script. Also is possible to use external file with variables: source /path/to/file/with/variables
  3. Use full path to commands /usr/bin/ls
  4. Do not rely on your user home, path, etc

And here is a example how you can create one shell script which run ruby program in different environments.

In cron you have records like (example):

0 1 * * * /path/script 1
0 2 * * * /path/script 2

The script itself is something like:

#!/bin/bash
a=$1
case "$a" in

1)  source /path/file1
    /path/to/ruby <parameters>
    ;;
2)  source /path/file2
    /path/to/ruby <parameters>
    ;;
<snip>

*) # do something if parameter is not enumerated
   ;;
esac

and file1 contain something like (example)

RUBYVAR1_1=1
RUBYVAR1_2=2

and file2

RUBYVAR2_1=12
RUBYVAR2_2=22
lk flag
The 70 or so commands that I have on my crontab generated by whenever are Ruby scripts. If you mean wrapping them with 70 bash scripts, that would be quite cumbersome, but also, by that point, they lost access to the environment variables with the credentials which is where the variables are coming from (automatically injected by whenever).
Romeo Ninov avatar
in flag
@PabloFernandez, I show you in the answer a way to move variables in side file which is included in bash scripts. And instead of generating 70 bash files why you do not run your ruby script in cron? If you do not how just ask
Score:0
in flag

man 5 crontab

An active line in a crontab will be either an environment setting or a cron command. An environment setting is of the form,

 name = value

where the spaces around the equal-sign (=) are optional, and any subsequent non-leading spaces in value will be part of the value assigned to name. The value string may be placed in quotes (single or double, but matching) to preserve leading or trailing blanks.

So enclosing your string containing double quotes with single quotes should work

Tested with a crontab:

var = 'this"contains"quotes'

* * * * * /usr/bin/env  >> /tmp/env

Which looks like it will properly store your double quotes in the var.

cat /tmp/env

HOME=/home/HBruijn
LANG=C.UTF-8
SHELL=/bin/sh
var=this"contains"quotes

But also I agree with the previous answer and sentiment; cron is not a proper scripting environment, it is just an ancient job scheduler with many limitations and you should offload anything that resembles complexity and include that in the job itself.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.