Короткий вопрос:
Почему может мы управлять файлом только для чтения в использовании Vim: + w + q +! даже, не будучи администратором?
Долгий вопрос:
У меня есть текстовый файл (myFile.txt), который только для чтения для всех:
navid@navid-ThinkPad-T530:~/ubuntuTest$ ls -l myFile.txt
-r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt
Я могу открыть его с Vim, не имея административных привилегий:
navid@navid-ThinkPad-T530:~/ubuntuTest$ vi myFile.txt
Я изменяю его и нажатие: Esc +: + w + q + Входят, и я вижу это сообщение об ошибке:
E45: 'readonly' option is set (add ! to override)
До сих пор все имеет смысл. Но когда я нажимаю: Esc +: + w + q +! + Входят, Vim сохраняет изменения.
Я использую Ubuntu 16.04 и VIM 7.4.
Как уже упоминал @Rob , вы можете сделать это, только если у вас есть доступ на запись к каталог, содержащий файл. Попытка сделать то же самое с файлом в, например, / etc
не удастся.
Что касается того, как vim
это делает, он удаляет файл и воссоздает его. Чтобы проверить это, я создал файл, принадлежащий пользователю root:
echo foo | sudo tee fff
, а затем приступил к редактированию файла с помощью vim
описанным вами способом, но присоединил процесс к strace
к посмотрите, что происходит:
strace vim fff 2> strace.out
Затем я проверил strace.out
и обнаружил:
unlink("fff") = 0
open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "foasdasdao\n", 11) = 11
Итак, файл был сначала удален ( unlink ("fff")
), затем был создан новый был создан файл с тем же именем ( open ("fff", O_WRONLY | O_CREAT | O_TRUNC, 0644)
), и в него были записаны внесенные мной изменения ( write (4, "foasdasdao \ п ", 11)
). Если вы попробуете это дома, то увидите, что после редактирования с помощью vim
файл теперь будет принадлежать вам, а не root.
Итак, строго говоря, vim
не редактирует файл, к которому у вас нет доступа на запись. Он удаляет файл из каталога, к которому у вас есть доступ на запись, а затем создает новый файл, к которому, опять же, у вас есть доступ на запись.
Используя w!
, вы удаляете исходный файл (, что вам разрешено ) и вместо этого записываете свою версию.
Когда вы Имея права записи в каталог, вы можете: создавать, перемещать или удалять файлы в этом каталоге.
$ mkdir foo
$ echo hi > foo/file
$ chmod 777 foo
$ chmod 700 foo/file
$ ls -l foo/file
-rwx------ 1 ravexina ravexina 7 Aug 31 03:19 foo/file
Теперь позвольте мне переключить моего пользователя и изменить файл
$ sudo -u user2 -s
$ vi foo/a # save using w! (I wrote into the file bye)
$ ls -l foo/a
-rwx------ 1 user2 user2 7 Aug 31 03:20 foo/file
Теперь посмотрим, что там:
$ cat foo/file
bye
Пока вы владеете родительским каталогом, вы можете удалить или заменить файл независимо от разрешения, поскольку вы можете изменить содержимое каталога :).
Попробуйте это с помощью другой команды как и rm, он предложит вам, но вы все равно можете это сделать. Сделайте каталог недоступным для записи, и это должно остановить его.
Дополнение:
Только что попробовал, но пока у меня есть файл, я все еще могу изменять его, даже если папка только для чтения. Однако, когда я меняю владельца на root:root не может открыть файл для записи. Таким образом решаются изменения файлов, принадлежащих root (или кому-то еще)
См. : help 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).
Поскольку у вас есть права на запись в каталог (то есть вы можете создавать, удалять или переименовывать файлы в нем), система позволяет это .
Значение по умолчанию cpoptions
не содержит W
:
'cpoptions' 'cpo' cpo
'cpoptions' 'cpo' string (Vim default: "aABceFs",
Vi default: all flags)
global
Это предупреждение VIM, которое может быть относительно важным, учитывая, как работают разрешения в UNIX. Очевидная неинтуитивность этого заключается в том, что файловые системы UNIX имеют разрешения для файла, хранящегося в i-узле файла. Структура каталогов как-то отделена и связывает только эти i-узлы. Каталоги также имеют свои разрешения, которые говорят, можете ли вы связывать / отключать файлы в нем, читать его или переходить к подкаталогам. Такой дизайн позволяет, чтобы один и тот же файл мог появляться в нескольких разных местах в структуре каталогов (через жесткие ссылки). Сказав «добавить! Для переопределения», VIM пытается предупредить вас, что исходный файл будет отключен (поэтому он останется нетронутым во всех других местах), а новый файл будет создан и связан с исходным местом в структуре каталогов. В случае, если счетчик ссылок исходного файла уменьшается до нуля, исходный файл будет освобожден, но если нет, вы фактически клонируете файл. Открытие файла также считается ссылкой, поэтому, если какая-то программа открыла файл и вы согласны «добавить! Для отмены», программа не увидит изменений, внесенных вами в файл с помощью VIM. Файл отключается от каталога только VIM, и после закрытия файла другой программой файл будет освобожден, если он не был связан где-то еще.
Обратите внимание, что в Windows,разрешения для файлов хранятся в каталоге, поэтому с точки зрения парадигмы разрешений Windows такое поведение vim может действительно выглядеть странно. Для записи в файл Windows по логике может также проверять права доступа к некоторым каталогам, даже к суперкаталогам. Как было сказано выше, в UNIX права доступа к каталогам не имеют отношения к манипуляциям с файлом, поскольку вы могли их перечислить и открыть (т.е. было x для всех суперкаталогов). Открытый файл в UNIX может даже не иметь имени файла, если он был отключен от всех каталогов после открытия.
Например, у вас есть файл / home / user1 / foo, и это тот же файл, что и (т.е. жестко привязанный к) / home / user2 / foo, и файл не доступен для записи никому и в настоящее время открыт программой P (открыт для чтения и записи программой, запущенной пользователем root). Если user1 открывает его с помощью vim и перезаписывает, он делает свою копию и больше не видит исходный файл. Если впоследствии user2 откроет свою ссылку с помощью vim и напишет в нее, ссылка снова будет отключена, и он создаст еще одну копию. Программа P по-прежнему будет видеть исходный файл и может свободно читать или писать в него. Как только программа закроет файл, файл исчезнет (будет освобожден файловой системой).
И ваш процесс редактора vim, и ваш файл принадлежат вам
getpwnam("navid")->pw_uid
, так что вы также можете выложить
:!chmod +w %
, и вы могли догадаться, что когда-то давным-давно был еще проще
:!rm %
( требуется только + w, но разрешение на отключение. и даже не право владения) стало слишком частым для того, чтобы кто-то мог вводить, так что vim был перепрограммирован так, чтобы автоматически предлагать и по запросу автоматически выполнять такую операцию.
Попробуйте перезаписать
/home/whoopi/.profile
своей старшей сестры как простой навид, и держите пари, что ваш vim даст вам желаемый отказ.
Это не совсем ответ, но если вы действительно хотите установить файл так, чтобы никто не мог измените или удалите его, вы можете сделать его неизменным.
Обычно, даже если файл принадлежит пользователю root, вы все равно можете удалить файл, если у вас есть права на запись в папку. Но когда вы делаете файл неизменяемым, даже root не может его изменить или удалить.
Чтобы сделать файл неизменяемым (вам нужно sudo
):
sudo chattr +i myFile.txt
Вы можете увидеть это с помощью lsattr
] (буква i
в результате):
$ lsattr myFile.txt
----i--------e-- myFile.txt
Чтобы снова сделать файл нормальным:
sudo chattr -i myFile.txt
Уточнение: когда файл неизменяемый, его нельзя удалить, переименовать, изменить или даже жестко -linked.
Стоит прочитать man chattr
, потому что файлы могут иметь ряд полезных атрибутов.
Вы также можете найти полезным "ограниченное удаление". Если он помещен в папку (а не в файл), это означает, что любому, кто создает файл в папке, разрешено изменять или удалять этот файл, но никто другой (кроме root). В папке / tmp
установлен этот флаг. Вы можете увидеть это с помощью флага t
на / tmp
:
$ ls -l --directory /tmp
drwxrwxrwt 10 root root 4096 Sep 6 09:00 /tmp
Чтобы установить или снять флаг ограниченного удаления в папке:
chmod +t myFolder # Add the restricted deletion flag.
chmod -t myFolder # Remove the restricted deletion flag.