What does the '!' really do when it's added to an ex command (:wq! | :w! | :q! )?

! generally means what you'd expect from "force", but what it means for specific command depends on the command. In the case of w!, if Vim cannot write to the file for some reason, it will try to delete and create a new one with the current buffer's contents.

Consider the following example (observe the inode numbers):

$ touch foo
$ chmod -w foo
$ stat foo
  File: ‘foo’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 22h/34d Inode: 10396141    Links: 1
Access: (0444/-r--r--r--)  Uid: ( 1000/ muru)   Gid: ( 1000/ muru)
Access: 2015-09-10 00:24:28.259290486 +0530
Modify: 2015-09-10 00:24:28.259290486 +0530
Change: 2015-09-10 00:24:30.771263735 +0530
 Birth: -
$ vim -c 'r!date' -c 'wq!' foo
$ stat foo                    
  File: ‘foo’
  Size: 30          Blocks: 8          IO Block: 4096   regular file
Device: 22h/34d Inode: 10396151    Links: 1
Access: (0444/-r--r--r--)  Uid: ( 1000/ muru)   Gid: ( 1000/ muru)
Access: 2015-09-10 00:24:37.727189657 +0530
Modify: 2015-09-10 00:24:37.731189614 +0530
Change: 2015-09-10 00:24:37.763189273 +0530
 Birth: -
$ cat foo
Thu Sep 10 00:24:37 IST 2015

That's why the owner and group changes. Permissions are preserved - :h write-permissions:

                                                    write-permissions
When writing a new file the permissions are read-write.  For unix the mask is
0666 with additionally umask applied.  When writing a file that was read Vim
will preserve the permissions, but clear the s-bit.

If you want to make Vim refuse writes, see :h write-readonly:

                                                    write-readonly
When the 'cpoptions' option contains 'W', Vim will refuse to overwrite a
readonly file.  When 'W' is not present, ":w!" will overwrite a readonly file,
if the system allows it (the directory must be writable).

Note that it says "the directory must be writable" - because without a writable directory, Vim can neither delete nor create a new file.


As stated in vim(1), -R ensures that the file will not be accidentally overwritten when the user blindly says :w, but doesn’t disable writing with :w!.

But it’s only an application, and when about to actually do something with files, the OS kernel will check permissions anyway. An experiment: I ran

strace vim /etc/hostname 2>vim.out

under a user. Even without explicit -R it started in readonly, because it looked at permissions. After changing the buffer

W10: Warning: Changing a readonly file

appeared.

Now :w and I got

E45: 'readonly' option is set (add ! to override)

I applied the suggestion and

"/etc/hostname" E212: Can't open file for writing

Predictably, in vim.out we see:

open("/etc/hostname", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)

Tags:

Vim