Mentioned here as well: https://stackoverflow.com/questions/13312794/inotify-dont-treat-vim-editting-as-a-modification-event

Really frustrating issue, how can I force vim to write the file?

It seems Vim does something strange when writing a file. It does not seem to invoke any of the [Create, Modify, CloseWrite, Move] inotify events. Only initially. on the first change.

Seems that it "deletes" the file, and hence the inotify watch becomes invalid (hence only works once)... How can I work around this?

  • 2
    Can you try the utility entr?
    – Mass
    Commented May 1, 2020 at 23:55

3 Answers 3


Which inotify events are fired depends on how Vim writes the file. This is controlled by multiple options.

In a typical setup it works like this. Assume Vim wants to write the file e.txt

  1. Vim moves the file e.txt to e.txt~
  2. Vim creates a new file e.txt and writes its content

In this case the event MOVE_SELF would be fired. As tools like inotifywait (with -m for "monitor") monitor the file by inode, so it would now in fact monitor the backup file e.txt~.

If Vim writes the same file again, the sequence is like this (note: the backup file already exists):

  1. Vim deletes the backup file e.txt~
  2. Vim moves the file e.txt to e.txt~
  3. Vim creates a new file e.txt and writes its content

So a monitoring inotifywait will receive a DELETE_SELF because the backup file is deleted. Now it listens to changes to an unused inode and will not print anything anymore.

If the file e.txt is in fact a symbolic link to the file tgt.txt, Vim acts different:

  1. Vim copies the content of tgt.txt (the symlinked file) to the backup file e.txt~
  2. Vim writes the content to tgt.txt.

In this case a monitoring inotifywait will see the CLOSE_WRITE (and other) events.

The behavior how Vim saves the file is controlled by the option backupcopy. In nocompatible mode it is set to auto. This means that Vim decides which is the best way to save a file. Hence the two different behaviors described above.

If backupcopy is set to yes, Vim will always create the backup file by copying the original file. In this case inotifywait is able to monitor the file.

If backupcopy is set to no, Vim will always create the backup file by moving the original file. In this case inotifywait is not able to monitor the file. This also has the disadvantage that it will break symbolic links.

See :help 'backupcopy'. This describes the pros and cons of the different values.

So back to inotify: How to monitor a file saved by Vim?

Assuming you want to monitor the file /home/joedoe/e.txt for CLOSE_WRITE events in a shell script:

file_dir="$(dirname "$file")"
inotifywait -mqe close_write --format "%w%f" "$file_dir" |
    while read -r filename; do
        if [ "$filename" = "$file" ]; then
            # do what needs to be done

This way you are independent from the strategy Vim uses for saving the file.


Found a hint to one solution here:


:set backupcopy=yes

Seems there may be some risk with this approach though.

  • You actually need to disable backupcopy for that, and the command is set nobackupcopy (not backupcopy=no or something like that...)
    – filbranden
    Commented May 1, 2020 at 21:37
  • 1
    That gave me an error, maybe cause I'm using neovim? Commented May 1, 2020 at 22:37
  • actually you're correct, it's a string... But it seems to me you need backupcopy=no for the rewrite to happen and trigger inotify.
    – filbranden
    Commented May 1, 2020 at 23:05
  • One other thing you can do is set an inotify on the directory (not file) and look for rename (move_to) actions there, look for the filename that was moved there and see if it matches the one you were looking for. But it would be really hard to do that with inotifywait, I think you probably need a C or Python etc. tool that would implement that for you...
    – filbranden
    Commented May 1, 2020 at 23:06
  • @filbranden yes means to copy the file to create a backup and then overwrite the original. So inotify will trigger. no means that the original file is renamed to create a backup and a new file with the original name is created.
    – Ralf
    Commented May 1, 2020 at 23:22

If this happens with Vim it's likely due to the way it 'saves' a file (it does this to avoid data loss). As a workaround, we can instead use inotify to watch the parent directory instead.

#!/usr/bin/env bash


inotifywait -r -m . | 
   while read -r file_path file_event file_name; do
       if echo "$file_name" | grep -q "$watchThisFile"; then               
         echo "$watchThisFile was modified"
         echo "Skipping:"
         echo "$file_path $file_event $file_name"
  • 1
    Using a filename as the pattern for grep is probably not correct; in particular, grep z.sh will match zash, z0sh, etc. Better might be this if your Grep supports -z, but -F is POSIX and would fix this specific case.
    – D. Ben Knoble
    Commented May 25, 2023 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.