Получение прав root для файла внутри vi?
Часто при редактировании файлов конфигурации я открываю один с vi, а затем, когда я иду, чтобы сохранить его, понимаем, что я не печатал
sudo vi filename
Есть ли способ предоставить vi sudo привилегии для сохранения файла? Кажется, я вспоминаю что-то об этом, глядя на некоторые вещи о vi некоторое время назад, но теперь я не могу его найти.
Ответы
Ответ 1
%
заменяется текущим именем файла, поэтому вы можете использовать:
:w !sudo tee %
(vim
обнаружит, что файл был изменен и спросит, хотите ли вы, чтобы он был перезагружен. Скажите да, выбрав [L]
а не OK.)
В качестве ярлыка вы можете определить свою собственную команду. Поместите следующее в ваш .vimrc
:
command W w !sudo tee % >/dev/null
С помощью вышеперечисленного вы можете набрать :W<Enter>
чтобы сохранить файл. Так как я написал это, я нашел более хороший способ (по моему мнению) сделать это:
cmap w!! w !sudo tee >/dev/null %
Таким образом, вы можете ввести :w!!
и он будет расширен до полной командной строки, оставив курсор в конце, так что вы можете заменить %
на собственное имя файла, если хотите.
Ответ 2
В общем случае вы не можете изменить действительный идентификатор пользователя в процессе vi, но вы можете сделать это:
:w !sudo tee myfile
Ответ 3
Общие оговорки
Самый распространенный способ обойти проблему только для чтения - открыть канал для текущего файла в качестве суперпользователя, используя реализацию sudo tee
. Тем не менее, все самые популярные решения, которые я нашел в Интернете, имеют несколько возможных препятствий:
- Весь файл записывается на терминал, а также в файл. Это может быть медленным для больших файлов, особенно при медленных сетевых подключениях.
- Файл теряет свои режимы и аналогичные атрибуты.
- Пути файлов с необычными символами или пробелами могут быть неправильно обработаны.
Решение
Чтобы обойти все эти проблемы, вы можете использовать следующую команду:
" On POSIX (Linux/Mac/BSD):
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
" Depending on the implementation, you might need this on Windows:
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >NUL'
Они могут быть сокращены, с уважением:
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'
Объяснение
:
начинает команду; вам нужно будет ввести этот символ в нормальном режиме, чтобы начать вводить команду. Он должен быть опущен в сценариях.
sil[ent]
подавляет вывод команды. В этом случае мы хотим остановить приглашение Press any key to continue
-like, которое появляется после запуска команды :!
.
exec[ute]
выполняет строку как команду. Мы не можем просто запустить :write
, потому что он не будет обрабатывать необходимый вызов функции.
!
представляет команду :!
: единственная команда, которую принимает :write
. Обычно :write
принимает путь к файлу, к которому следует писать. :!
сам запускает команду в оболочке (например, используя bash -c
). С помощью :write
он запустит команду в оболочке, а затем напишет весь файл на stdin
.
sudo
должен быть очевиден, так как вы здесь. Выполните команду как суперпользователя. В сети есть много информации о том, как это работает.
tee
pipe stdin
в данный файл. :write
будет записываться в stdin
, тогда суперпользователь tee
получит содержимое файла и напишет файл. Он не будет создавать новый файл - просто перезапишите содержимое, поэтому сохраняются режимы и атрибуты файлов.
shellescape()
выделяет специальные символы в заданном пути к файлу в соответствии с текущей оболочкой. Только с одним параметром он, как правило, просто вставляет путь в кавычки по мере необходимости. Поскольку мы отправляем в полную командную строку оболочки, мы хотим передать ненулевое значение в качестве второго аргумента, чтобы включить обратное слэш-экранирование других специальных символов, которые могли бы в противном случае отключить оболочку.
@%
читает содержимое регистра %
, в котором содержится текущее имя файла буфера. Это не обязательно абсолютный путь, поэтому убедитесь, что вы не изменили текущий каталог. В некоторых решениях вы увидите, что символ коммерческого символа опущен. В зависимости от местоположения %
является допустимым выражением и имеет тот же эффект, что и при чтении регистра %
. Вложенное внутри другого выражения, однако, ярлык обычно запрещен: например, в этом случае.
>NUL
и >/dev/null
перенаправить stdout
на нулевое устройство платформы. Несмотря на то, что мы отключили команду, мы не хотим, чтобы все накладные расходы, связанные с трубопроводом stdin
, обратно на vim, лучше всего сбросили его как можно раньше. NUL
- это нулевое устройство в DOS, MS-DOS и Windows, а не в допустимом файле. Что касается перенаправления Windows 8 на NUL, это не приводит к записи файла с именем NUL. Попробуйте создать файл на рабочем столе с именем NUL с расширением файла или без него: вы не сможете этого сделать. (В Windows есть несколько других имен устройств, которые можно было бы узнать.)
~/.vimrc
В зависимости от платформы
Конечно, вы все равно не хотите запоминать их и набирать каждый раз. Гораздо проще сопоставить соответствующую команду с более простой пользовательской командой. Для этого в POSIX вы можете добавить следующую строку в свой файл ~/.vimrc
, создав ее, если она еще не существует:
command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
Это позволит вам ввести команду: W (с учетом регистра) для записи текущего файла с правами суперпользователя - намного проще.
Платформа зависящего
Я использую независимый от платформы файл ~/.vimrc
, который синхронизируется на разных компьютерах, поэтому я добавил многоплатформенные функции для моего. Здесь a ~/.vimrc
с только соответствующими настройками:
#!vim
" Use za (not a command; the keys) in normal mode to toggle a fold.
" META_COMMENT Modeline Definition: {{{1
" vim: ts=4 sw=4 sr sts=4 fdm=marker ff=unix fenc=utf-8
" ts: Actual tab character stops.
" sw: Indentation commands shift by this much.
" sr: Round existing indentation when using shift commands.
" sts: Virtual tab stops while using tab key.
" fdm: Folds are manually defined in file syntax.
" ff: Line endings should always be <NL> (line feed #09).
" fenc: Should always be UTF-8; #! must be first bytes, so no BOM.
" General Commands: User Ex commands. {{{1
command W call WriteAsSuperUser(@%) " Write file as super-user.
" Helper Functions: Used by user Ex commands. {{{1
function GetNullDevice() " Gets the path to the null device. {{{2
if filewritable('/dev/null')
return '/dev/null'
else
return 'NUL'
endif
endfunction
function WriteAsSuperUser(file) " Write buffer to a:file as the super user (on POSIX, root). {{{2
exec '%write !sudo tee ' . shellescape(a:file, 1) . ' >' . GetNullDevice()
endfunction
" }}}1
" EOF
Ответ 4
Если вы используете Vim, существует script доступный с именем sudo.vim. Если вы обнаружите, что вы открыли файл, доступ к которому вам нужен для доступа root, введите
:e sudo:%
Vim заменит% на имя текущего файла, а sudo:
инструктирует sudo.vim script взять на себя ответственность за чтение и письмо.
Ответ 5
Совет Райана, как правило, хорош, однако, если следующий шаг 3, не перемещайте временный файл; у него будут неправильные права собственности и разрешения. Вместо этого sudoedit
правильный файл и прочитайте содержимое (используя :r
или тому подобное) временного файла.
Если следующий шаг 2, используйте :w!
, чтобы заставить файл быть записан.
Ответ 6
Когда вы переходите в режим вставки в файл, вам нужен sudo-доступ для редактирования, вы получаете сообщение о состоянии
-- INSERT -- W10: Warning: Changing a readonly file
Если я пропущу это, обычно я делаю
:w ~/edited_blah.tmp
:q
.. то..
sudo "cat edited_blah.tmp > /etc/blah"
.. или..
sudo mv edited_blah.tmp /etc/blah
Вероятно, существует менее окольный способ сделать это, но он работает.
Ответ 7
Быстрый Google, похоже, дает следующий совет:
- Не пытайтесь редактировать, если он доступен только для чтения.
- Возможно, вы сможете изменить права доступа к файлу. (Независимо от того, позволит ли вам сэкономить до эксперимента.)
- Если вы все равно отредактировали, сохраните во временный файл и переместите его.
http://ubuntuforums.org/showthread.php?t=782136
Ответ 8
Вот еще один вопрос, который появился после ответа на этот вопрос: плагин под названием SudoEdit, который предоставляет функции SudoRead и SudoWrite, которые по умолчанию будут пытаться использовать sudo first и su, если это не удается: http://www.vim.org/scripts/script.php?script_id=2709
Ответ 9
У меня это в моем ~/.bashrc:
alias svim='sudo vim'
Теперь, когда мне нужно отредактировать файл конфигурации, я просто открываю его с помощью svim.
Ответ 10
Быстрый взлом, который вы можете рассмотреть, - это сделать chmod в файле, который вы редактируете, сохранить с помощью vim, а затем chmod обратно в исходный файл.
ls -l test.file (to see the permissions of the file)
chmod 777 test.file
[This is where you save in vim]
chmod xxx test.file (restore the permissions you found in the first step)
Конечно, я не рекомендую этот подход в системе, где вас беспокоит безопасность, так как на несколько секунд любой может читать/изменять файл, не понимая.
Ответ 11
используйте gksudo вместо sudo для GVim i.e.
cmap w!! w !gksudo tee >/dev/null %