1

Trying to add text on the line before that it find the match (updateKey.sh) in this case, but won't get it to work. Here is my crontab file that the script adds the line to

0 06,18 * * * /home/server/scripts/CCgenerator.sh
0 05 * * * /home/server/scripts/updateKey.sh

The first line "CCgenerator.sh" is sometimes deleted but it has to look like that. And here is the script that adds that line.

#!/bin/bash
CCgenerator="0 06,18 * * * /home/server/scripts/CCgenerator.sh"
updateKey="0 05 * * * /home/server/scripts/updateKey.sh"


if ! sudo grep -q "$CCgenerator" /var/spool/cron/crontabs/root; then
    echo "Adds CCgenerator.sh"
    sudo sed -i '/\$updateKey/i $CCgenerator' /var/spool/cron/crontabs/root
    else
    echo "CCgenerator.sh found"
fi
exit
5
  • Please take a look at editing-help.
    – Cyrus
    May 8, 2016 at 18:38
  • Do you mean sudo sed -i '/\"($updateKey.sh)"/i "($CCgenerator)" ' /var/spool/cron/crontabs/root May 8, 2016 at 18:42
  • (1) I don’t see why don_crissti suggested braces; they don’t seem to be needed in this case. (2) A simplistic answer would be sed -i "/$updateKey/i $CCgenerator", but that will fail because $updateKey contains slashes.  sed will see "/0 05 * * * /home/server/scripts/updateKey.sh/i 0 06,18 * * * /home/server/scripts/CCgenerator.sh", which will fail.  You should be able to handle the slashes with sed -i "\|$updateKey|i $CCgenerator" (using a character that doesn't appear in $updateKey), but this will still have a problem with the asterisks, and I’m not sure how to handle them easily. May 8, 2016 at 20:03
  • 3
    Possible duplicate of Bash add text on line script
    – cas
    May 13, 2016 at 10:58
  • Thank you for showing your source file. What is the transformed result you want to achieve? May 19, 2016 at 9:32

3 Answers 3

1

For cron edit purpose l0b0 answer is the best way, to fix your script you have to:

  • escape dots and asterisk in your search key (updateKey)
  • use alternative separator in sed (I choose %)
  • double quotes around sed expression (you want your bash variables resolved)

#!/bin/bash
CCgenerator="0 06,18 * * * /home/server/scripts/CCgenerator.sh"
updateKey="0 05 \* \* \* /home/server/scripts/updateKey\.sh"

if ! grep -q "$CCgenerator" cron; then
    echo "Adds CCgenerator.sh"
    sed -i "\%$updateKey%i $CCgenerator" cron
else
    echo "CCgenerator.sh found"
fi
exit
1
  • I'm not able to run "cron" that's why I run the file /var/spool/cron/crontabs/root.. May 9, 2016 at 8:20
1

Rather than update the crontab directly you'll want to use a standard mechanism to add a cron job:

line="* * * * * /path/to/command"
(crontab -u userhere -l; echo "$line" ) | crontab -u userhere -
1
  1. Don't edit a crontab file directly. Use the crontab command, that's what it's for.

  2. Don't use sudo multiple times in a script. Run the entire script with sudo.

  3. Quote your variables and strings properly. Single-quotes around literal strings, Double-quotes for variable etc interpolation.

  4. You should be grepping for fixed strings rather than regular expressions, so use grep -F. Otherwise the *s in the patterns will be interpreted as "zero or more spaces".

  5. You don't need exit at the end of a script unless you want to set a specific return value (which you aren't doing). The script is going to exit at the end anyway.

  6. You're grepping for the existence of the CCgenerator.sh crontab entry, but then just assuming that the updateKey.sh exists.

  7. More importantly, why do you even care where in the crontab the CCgenerator.sh rule is? It works just as well if it's at the beginning or end of the file. So you don't even need to search for updateKey.sh anyway.

This should address all of the above points:

#! /bin/bash
CCgenerator='0 06,18 * * * /home/server/scripts/CCgenerator.sh'

if ! crontab -u root -l | grep -Fq "$CCgenerator" ; then
    echo 'Adding CCgenerator.sh'
    # append "$CCgenerator to end of root's crontab
    (crontab -u root -l ; printf '%s\n' "$CCgenerator") | crontab -u root
else
    echo 'CCgenerator.sh found'
fi

If you really don't don't want to run the entire script with sudo then add sudo before every use of the crontab command.

And if you actually care where the CCGenerator.sh line is relative to the updateKey.sh line then:

#! /bin/bash
CCgenerator='0 06,18 * * * /home/server/scripts/CCgenerator.sh'
updateKey='0 05 \* \* \* /home/server/scripts/updateKey\.sh'

if ! crontab -u root -l | grep -Fq "$CCgenerator" ; then
    echo 'Adding CCgenerator.sh'
    crontab -u root -l | sed -e "\:$updateKey: i\
$CCgenerator
" | crontab -u root
    else
    echo 'CCgenerator.sh found'
fi

This will, however, fail to do anything if $updateKey isn't in the crontab. A better version would grep for $updateKey, runthe sed command to insert $CCgenerator if it existed, otherwise use something like the subshell with crontab -u root -l ; printf ... I used to append $CCgenerator to the end of the crontab.

Maybe something like this:

#! /bin/bash
CCgenerator='0 06,18 * * * /home/server/scripts/CCgenerator.sh'
updateKey='0 05 \* \* \* /home/server/scripts/updateKey\.sh'

# we're going to use `crontab -u root -l` multiple times, it's
# best to just fetch it once and store it in a variable.
rootcrontab="$(crontab -u root -l)"

if ! grep -Fq "$CCgenerator" <<<"$rootcrontab"; then
    if grep -q "$updateKey" <<<"$rootcrontab" ; then
        echo 'Inserting CCgenerator.sh'
        echo "$rootcrontab" | sed -e "\:$updateKey: i\
$CCgenerator
" | crontab -u root
    else
        echo 'Appending CCgenerator.sh'
        printf '%s\n' "$rootcrontab" "$CCgenerator" | crontab -u root
    fi
else
    echo 'CCgenerator.sh found'
fi

NOTE: $updateKey already has its * characters escaped, so we don't need to use grep -F.

1
  • BTW, man crontab mentions that it uses stdin if you give it a filename of -. It also uses stdin if you don't give it a filename at all, but this is undocumented....at least in the version of crontab I'm using (vixie cron 3.0pl1 on debian sid). Add the - pseudo-filename if it doesn't work for your version of crontab.
    – cas
    May 8, 2016 at 23:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .