Using Vim to Edit Crontab Entries on Slackware

For the longest time I’ve had issues editing crontab entries for the root user when setting the VISUAL environment variable to /usr/bin/vim and using “crontab -e”. The existing crontab would be displayed in the editor. I could make changes and save them. However, the changes weren’t written to actual crontab file for root. I had no such problems when modifying a the crontab for a normal user. This behavior may be specific to Slackware or be due to some quirk with the versions of cron and vim used by Slackware (Slackware uses dcron).

When I first ran across this I remember spending some time trying to find a solution, but didn’t come up with anything. My work around has been to maintain a file with my crontab entries and then run “crontab filename“, which puts the contents of the file in to the real crontab. This approach has served me well for quite some time, but for some reason I decided to dig in to this again today.

Why can I successfully use vim and “crontab -e” with a normal user, but not for root? I discovered that when editing a normal user’s crontab, the inode number for the temporary file created with “crontab -e” did not change between initial open and a save. I tested this by using “stat /var/spool/cron/crontab.xxxxxx” (xxxxxx were some random characters) on the file when it was first created and then again after a save. However, the same test when running “crontab -e” as root showed that the inode number for the temp file changed. Vim was creating a new file with the same name, but it turns out cron requires the file be edited in place.

Reading through Vim’s online help I ran across a paragraph in the “backupcopy” entry that specifically mentions problems with “crontab -e”. The text states the following:

One situation where “no” and “auto” will cause problems: A program
that opens a file, invokes Vim to edit that file, and then tests if
the open file was changed (through the file descriptor) will check the
backup file instead of the newly created file. “crontab -e” is an
example.

Now I was getting somewhere. I added the following to root’s .vimrc:

set bkc=yes

Sure enough after this change the inode for the temp file did not change between initial creation and a save. I am now able to successfully use “crontab -e” to edit root’s crontab.

I don’t know the exact reason why there was a discrepancy between the behavior of “crontab -e” for a normal user and for root, but I have a guess. The crontab binary is suid root. It creates a temp file owned by the user and group executing “crontab -e” in a location to which that user may not have write access. This forces vim to edit the file in place when run as a normal user. However, when run as root vim is able to overwrite the initial temp file with a new one. Setting “bkc” or “backupcopy” to yes in root’s .vimrc forces vim to modify the file in place. See vim’s online help for more information on how that setting works (“:h bkc” from within vim will get you to where you need to go).

Jul 29th, 2010 | Posted in Linux
Comments are closed.