I understand that it means force to do something.
When doing $ vim -R file I enter in read-only mode, but this works as preventive mode only
-R Readonly mode. The 'readonly' option will be set for all the
files being edited. You can still edit the buffer, but will
be prevented from accidentally overwriting a file. If you
forgot that you are in View mode and did make some changes,
you can overwrite a file by adding an exclamation mark to
the Ex command, as in ":w!". The 'readonly' option can be
reset with ":set noro" (see the options chapter, |options|).
Subsequent edits will not be done in readonly mode. Calling
the executable "view" has the same effect as the -R argument.
The 'updatecount' option will be set to 10000, meaning that
the swap file will not be updated automatically very often.
But what I can’t get yet is why it makes the instruction to skip permissions even if the file’s owner is root user, besides it also change owner & group.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
! 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.
Method 2
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)
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0