Получение root-прав на файл внутри vi? - PullRequest
238 голосов
/ 04 августа 2008

Часто при редактировании конфигурационных файлов я открываю один с помощью vi, а затем, когда иду, чтобы сохранить его, понимает, что я не набрал

sudo vi filename

Есть ли способ предоставить привилегии vi sudo для сохранения файла? Кажется, я вспомнил, что видел что-то об этом, когда искал кое-что о vi некоторое время назад, но сейчас я не могу его найти.

Ответы [ 11 ]

288 голосов
/ 31 августа 2008

% заменяется текущим именем файла, поэтому вы можете использовать:

:w !sudo tee %

(vim обнаружит, что файл был изменен, и спросит, хотите ли вы его перезагрузить. Скажите «да», выбрав [L] вместо «OK».)

В качестве ярлыка вы можете определить свою собственную команду. Поместите в ваш .vimrc следующее:

command W w !sudo tee % >/dev/null

Вы можете набрать :W<Enter>, чтобы сохранить файл. С тех пор, как я написал это, я нашел более хороший способ (на мой взгляд) сделать это:

cmap w!! w !sudo tee >/dev/null %

Таким образом, вы можете набрать :w!!, и он будет расширен до полной командной строки, оставив курсор в конце, так что вы можете заменить % на собственное имя файла, если хотите.

32 голосов
/ 04 августа 2008

Как правило, вы не можете изменить эффективный идентификатор пользователя процесса vi, но вы можете сделать это:

:w !sudo tee myfile
15 голосов
/ 13 октября 2012

Общие предостережения

Наиболее распространенный способ обойти проблему файла, доступного только для чтения, - открыть канал для текущего файла в качестве суперпользователя, используя реализацию sudo tee. Тем не менее, все самые популярные решения, которые я нашел в Интернете, имеют несколько возможных предостережений:

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

* Решения 1014 * Чтобы обойти все эти проблемы, вы можете использовать следующую команду: " 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, которое появляется после выполнения команды :!.

exec[ute] выполняет строку как команду. Мы не можем просто запустить :write, потому что он не обработает необходимый вызов функции.

! представляет команду :!: единственная команда, которую принимает :write. Обычно :write принимает путь к файлу для записи. :! самостоятельно запускает команду в оболочке (например, используя bash -c). С :write он запустит команду в оболочке, а затем запишет весь файл в stdin.

sudo должно быть очевидно, потому что именно поэтому вы здесь. Запустите команду как суперпользователь. В сети есть много информации о том, как это работает.

tee трубы 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, который синхронизируется между компьютерами, поэтому я добавил к своим функциям мультиплатформенность. Вот ~/.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
11 голосов
/ 24 сентября 2008

Если вы используете Vim , существует сценарий с именем sudo.vim . Если вы обнаружили, что открыли файл, для чтения которого вам нужен root-доступ, введите

:e sudo:%
Vim заменяет% на имя текущего файла, а sudo: указывает, что скрипт sudo.vim вступает во владение для чтения и письменная форма.
7 голосов
/ 04 августа 2008

Совет Райана, как правило, хорош, однако, если вы выполните шаг 3, не перемещайте временный файл; у него будут неправильные права собственности и права доступа. Вместо этого sudoedit правильный файл и прочитайте содержимое (используя :r или подобное) временного файла.

Если выполнить шаг 2, используйте :w!, чтобы принудительно записать файл.

3 голосов
/ 12 августа 2008

Когда вы входите в режим вставки файла, для редактирования которого вам нужен доступ 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

Вероятно, есть менее обходной способ сделать это, но это работает.

1 голос
/ 29 января 2010

Вот еще один, который появился после ответа на этот вопрос, плагин, названный SudoEdit, который предоставляет функции SudoRead и SudoWrite, которые по умолчанию будут пытаться сначала использовать sudo и su в случае сбоя: http://www.vim.org/scripts/script.php?script_id=2709

1 голос
/ 04 августа 2008

Быстрый Google, кажется, дает этот совет:

  1. Не пытайтесь редактировать, если оно доступно только для чтения.
  2. Возможно, вы сможете изменить разрешения для файла. (Позволит ли вам сэкономить, зависит от экспериментов.)
  3. Если вы все равно отредактировали, сохраните во временный файл, а затем переместите его.

http://ubuntuforums.org/showthread.php?t=782136

0 голосов
/ 30 ноября 2010

используйте гксудо вместо sudo для GVim, т.е.

cmap w!! w !gksudo tee >/dev/null %
0 голосов
/ 19 марта 2009

У меня есть это в моем ~ / .bashrc:

alias svim='sudo vim'

Теперь, когда мне нужно отредактировать файл конфигурации, я просто открываю его с помощью svim.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...