Ubuntu – Why can I modify a read-only file

chmodcommand linepermissionsread-onlyvim

Short Question:

Why can we manipulate a read-only file in Vim using : + w + q + ! even without being an administrator?

Long Question:

I have a text file (myFile.txt) which is read-only for everyone:

navid@navid-ThinkPad-T530:~/ubuntuTest$ ls -l myFile.txt 
-r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt

I can open it with Vim without having admin privileges:

navid@navid-ThinkPad-T530:~/ubuntuTest$ vi myFile.txt 

I modify it and press: Esc + : + w + q + Enter and I see this error message:

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

So far, everything makes sense.
But when I press: Esc + : + w + q + ! + Enter, Vim saves the changes.

I'm using Ubuntu 16.04 and VIM 7.4.

Best Answer

As @Rob already mentioned, you can only do this if you have write access to the directory containing the file. Attempting to do the same thing to a file in, for example, /etc will fail.

As for how vim is doing this, it deletes the file and recreates it. To test this, I created a file owned by root:

echo foo | sudo tee fff

And then proceeded to edit the file with vim in the way that you describe, but attaching the process to strace to see what's happening:

strace vim fff 2> strace.out

I then checked strace.out and found:

unlink("fff")                           = 0
open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "foasdasdao\n", 11)            = 11

So, the file was first deleted (unlink("fff")), then a new file of the same name was created (open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644)) and the modifications I had made were written to it (write(4, "foasdasdao\n", 11)). If you try this at home, you will see that after you edit it with vim, the file will now belong to you and not root.

So, strictly speaking, vim isn't editing a file you have no write access to. It is deleting a file from a directory to which you do have write access and then creating a new file to which, again, you have write access.