mila002 mila002 - 1 month ago 11
Linux Question

Using sed to replace text with slashes in crontab files

I'm trying to replace an entry in Crontab (RedHat) with sign #.
I tried sed command like this

sed -i 's|35 15 * * * /tmp/vii/test.sh >/dev/null 2>&1|#|g' /var/spool/cron/root


but it doesn't work. Any ideas?

Answer

Server file edition is a bad practice!

Don't try to edit crontab files directly, use crontab tools instead!!

Simple sed way

You could use:

crontab -l

to dump actual crontab list.

crontab -l | sed '/vii.test.sh/s/^/# /'

... or more finely:

crontab -l | sed '/^35 \+15.*vii.test.sh/s/^/# /'

to pre-edit crontab list and see on terminal sed command result

Then:

crontab -l | sed '/vii.test.sh/s/^/# /' | crontab

to replace actual crontab list, once everything are ok.

But warn!

wrong Command | crontab

will erase completely your crontab list!!

Scripted, line number based method

There is a little script:

#!/bin/sh

SED=`which sed`
CAT=`which cat`
CRONTAB=`which crontab`

lines=`$CRONTAB -l | wc -l`

$CRONTAB -l |
    $CAT -n

read -p 'Switch comment on line: ' line

if [ -n "$line" ] && [ $line -ge 1 ] && [ $lines -ge $line ]; then

    $CRONTAB -l |
    $SED $line'{ s/^# //;t;s/^/# /;: }'

    read -p 'Apply this? (y/[n])' apply
    [ "$apply" = "y" ] &&
    $CRONTAB -l |
        $SED $line'{ s/^# //;t;s/^/# /;: }' |
        $CRONTAB

fi

May produce:

     1  # For more information see the manual pages of crontab(5) and cron(8)
     2  #
     3  # m h  dom mon dow   command
     4  00  4    *   *   *   /path/to/another/command
     5  35 15 * * * /tmp/vii/test.sh >/dev/null 2>&1
Switch comment on line: 

From there, if you hit 5 (followed by return):

# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
00  4    *   *   *   /path/to/another/command
# 35 15 * * * /tmp/vii/test.sh >/dev/null 2>&1
Apply this? (y/[n])n

And you could press y if you're ok.

For users:

#!/bin/bash

mapfile -t cronTab < <(crontab -l)

paste <(seq 1 ${#cronTab[@]}) <(printf "%s\n" "${cronTab[@]}")

read -p "Switch comment on line: (1-${#cronTab[@]}) " line

(( (line>0) && (${#cronTab[@]}>=line) )) && { 

    [ "${cronTab[line-1]:0:1}" = "#" ] &&
    cronTab[line-1]="${cronTab[line-1]:2}" ||
    cronTab[line-1]="# ${cronTab[line-1]}"

    printf "%s\n" "${cronTab[@]}"
    read -p 'Apply this? (y/[n])' apply

    [ "$apply" = "y" ] &&
    printf "%s\n" "${cronTab[@]}" |
        crontab
}