Вопрос

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

sudo vi filename

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

Это было полезно?

Решение

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

:w !sudo tee %

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

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

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

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

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

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

Другие советы

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

:w !sudo tee myfile

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

Наиболее распространенный способ обойти проблему с файлом только для чтения - открыть канал к текущему файлу от имени суперпользователя, используя реализацию 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-подобное приглашение, которое появляется после запуска :! команда.

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

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

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

tee трубы stdin к данному файлу. :write напишу по адресу stdin, затем суперпользователь tee получит содержимое файла и запишет файл.Он не создаст новый файл - просто перезапишет содержимое, поэтому режимы и атрибуты файла будут сохранены.

shellescape() экранирует специальные символы в заданном пути к файлу в соответствии с текущей командной оболочкой.Имея только один параметр, он обычно просто заключает путь в кавычки по мере необходимости.Поскольку мы отправляем в командную строку полной оболочки, мы захотим передать ненулевое значение в качестве второго аргумента, чтобы включить экранирование обратной косой черты других специальных символов, которые в противном случае могли бы сбить с толку оболочку.

@% считывает содержимое % регистр, который содержит имя файла текущего буфера.Это не обязательно абсолютный путь, поэтому убедитесь, что вы не изменили текущий каталог.В некоторых решениях вы увидите, что символ commercial-at опущен.В зависимости от местоположения, % является допустимым выражением и имеет тот же эффект, что и чтение % Зарегистрироваться.Однако, вложенный в другое выражение ярлык обычно запрещен:как, например, в данном случае.

>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

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

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

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

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

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

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

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

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

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

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

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

alias svim='sudo vim'

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

Быстрый способ, который вы можете рассмотреть, - это выполнить 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)

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

использование гксудо вместо того, чтобы sudo для GVim , т. е.

cmap w!! w !gksudo tee >/dev/null %
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top