Примечание . Из-за устаревших причин лицензирования большинство дистрибутивов GNU/Linux не содержат оригинальную программу vi, написанную Биллом Джой. Вместо этого команда vi предоставляется при запуске Vim в режиме совместимости с vi. Следующий ответ основан на запуске Vim с его режимом совместимости с vi.
Изменение файла только для чтения
Vim предупреждает пользователя, если он изменяет буфер файла только для чтения, W10: Warning: Changing a readonly file
только для чтения. Если пользователь пытается записать в этот файл, он получает следующее сообщение об ошибке, 'readonly' option is set (add ! to override)
.
Когда родительский каталог доступен для записи пользователем Vim
Vim, будучи полезным, позволяет пользователю знать, что он может настаивать на написании, добавляя восклицательный знак !
к команде w
. Если используется эта принудительная версия команды записи, Vim удаляет исходный файл (при использовании Vim с установленным параметром backup
только для Vim исходный файл фактически переименовывается, чтобы совпадать с файлом резервной копии). Затем он открывает (создает) новый файл с тем же именем, что и оригинал, и записывает содержимое своего буфера в этот новый файл. Это можно увидеть, проверив inode файла до и после запуска Vim:
$ ls -l --inode t
131529 -r--r--r-- 1 anthony anthony 0 Apr 13 09:23 t
$ vi t
$ ls -l --inode t
131649 -r--r--r-- 1 anthony anthony 4 Apr 13 09:23 t
Примечание. Это также может изменить разрешение и владельца файла и разорвать (символические) ссылки, например, если исходный файл принадлежит другому пользователю, новый файл будет принадлежать пользователю, работающему под управлением Vim.
Процесс может сделать это, только если у него есть разрешение на запись в родительский каталог файла. В общем, чтобы программа не могла изменить файл, необходимо обеспечить разрешения как самого файла, так и его родительского каталога.
Когда родительский каталог недоступен для записи пользователем Vim
Однако даже в этом случае Vim по-прежнему старается помочь настойчивому пользователю перезаписать файл. Если пользователь Vim владеет файлом, Vim может обойти ограничение родительского каталога только для чтения, временно изменив разрешение файла (используя системный вызов chmod
), записав буфер в файл, закрыв файл, а затем изменив разрешения назад. Вот выдержка из системных вызовов, выполняемых при запуске vi через strace, strace -o ../vi.trace vi t
:
getuid() = 501
chmod("t", 0100644) = 0
open("t", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "I am good singer,\n", 18) = 18
fsync(4) = 0
close(4) = 0
chmod("t", 0100444) = 0
Примечание. Этого не происходит, если пользователь Vim редактирует файл, владельцем которого он не является, поскольку Vim не сможет изменить права доступа к файлу.
добавление
Чтобы быть уверенным, что файл не может быть изменен (в системе GNU/Linux), запустите команду chattr
от имени суперпользователя:
sudo chattr +i filename
От man chattr
:
Файл с атрибутом «i» не может быть изменен: его нельзя удалить или переименовать, нельзя создать ссылку на этот файл и данные не могут быть записаны в файл. Только суперпользователь или процесс, обладающий возможностью CAP_LINUX_IMMUTABLE, может установить или очистить этот атрибут.