Как сохранить файл, для которого у меня нет прав на запись?

26

Иногда случается, что я открываю файл и делаю некоторые изменения как мой собственный пользователь, не замечая или «забывая» замечать [read-only]предупреждение в строке состояния (то есть какой-то случайный /etcфайл конфигурации, например /etc/resolv.conf).

:w!очевидно, в этом случае происходит сбой, потому что мой пользователь не имеет разрешения на запись в любом случае. Так что я должен :w /home/filenameвыйти и sudo mv ...очень неудобно.

Есть ли способ, чтобы я мог временно перейти в root, чтобы иметь возможность сохранить файл, открытый в данный момент? (учитывая, что я в sudoersили / и я могу suнапрямую)?

Гвидо
источник

Ответы:

24

Хитрость заключается в том, чтобы использовать внешний вызов для sudo:

:w !sudo tee %

Как это работает:

  • :w !<command>выполняется <command>с содержимым буфера как stdin.
  • teeдублирует стандартный ввод в файл & стандартный вывод; %расширяется до текущего имени файла ..
  • Вы префикс это с sudoправами root.

Вы на самом деле не сохраняете файл с помощью Vim, скорее вы вызываете внешнюю программу, чтобы перезаписать содержимое редактируемого файла. Вот почему вы получите предупреждение от Vim:

W12: Warning: File "xxx" has changed and the buffer was changed in Vim as well
See ":help W12" for more info.
[O]K, (L)oad File: 

Вы можете превратить это в функцию:

fun! SuperWrite()
        write !sudo tee %
        " Or with :silent (but that doesn't seem to work for everyone)
        "silent write !sudo tee %
        edit!
endfun

И связка клавиш:

nnoremap <Leader>w! :call SuperWrite()<CR>

С su, только пользователь root может использовать -cдля немедленного выполнения команды. Я не думаю, что вы можете использовать suэто, но, возможно, есть хитрость, о которой я не знаю ...

Мартин Турной
источник
SuperWriteработает, но он возвращает файл обратно на вас. При его :silentзапуске вы вводите свой пароль невидимым.
TankorSmash
@TankorSmash Спасибо; обновленный ответ. Не уверен, что вы имеете в виду под «ввести свой пароль невидимым», хотя? Добавление, silentкажется, работает нормально?
Мартин Турной
Я не запускаю vim с sudo, так что это может быть здесь, но когда я иду на sudo tee, файл запрашивает пароль sudo. Если он молчит, я не вижу подсказку, но все равно нужно ввести пароль.
TankorSmash
1
То, что вы видите, - это стандартная функциональность эхо-запроса к стандартному выводу, а также предоставленный файл. Решение состоит в том, чтобы перенаправить стандартный вывод в / dev / null, а-ля: w ! tee % > /dev/null это будет по-прежнему отображать результат команды (одна строка), но не все содержимое буфера.
Джон Картер
Вместо того, чтобы использовать, а teeзатем выбрасывать свои выходные данные, catтакже не будет работать, если вы не хотите распечатывать файл?
Ли Райан
12

Я использую следующее сопоставление в моем .vimrc, которое я считаю полезным:

cnoremap w!! w !sudo tee %

Это легко запомнить, потому что wэто «запись» w!, «принудительная запись» и w!!«супер-принудительная запись». :П

Дверная ручка
источник
1
Я давно это сопоставил W, но w!!имеет больше смысла, обновлю мой .vimrc. Спасибо
jalanb