
В этом руководствее мы узнаем, как сохранить файл как sudo, не выходя из Vim.
Сначала мы изучим проблему и поймем, почему сохранять файлы от имени sudo не так просто, как от обычного пользователя.
Затем мы сосредоточимся на использовании tee внутри Vim для записи изменений от имени суперпользователя.
Наконец, мы обсудим скрипт sudo.vim в качестве альтернативы.
Проблема
Когда мы редактируем файл в Vim, наша возможность сохранить изменения может быть ограничена из-за прав доступа к файлу.
Например, мы можем по забывчивости редактировать системный файл некоторое время, а затем записать изменения обратно в файл, но обнаружить, что произошла ошибка в правах.
В Vim нет волшебной встроенной функции, которую мы могли бы использовать для отмены этих прав.
Это связано с тем, что каждый процесс в Linux запускается с определенным UID (идентификатором пользователя).
Кроме того, EUID (эффективный идентификатор пользователя) определяет права доступа, которыми обладает процесс.
Поэтому, когда мы запускаем Vim, процесс Vim наследует UID пользователя, который его запустил.
Проблема в том, что мы не можем напрямую изменить EUID процесса.
Поэтому мы не можем заставить процесс вести себя так, как будто он запущен суперпользователем.
Поэтому сохранять файл под другим именем и копировать изменения в исходный файл от имени суперпользователя довольно неудобно и неприятно.
Однако для таких случаев существуют быстрые обходные пути, которые мы рассмотрим в следующих разделах.ation в скриптах Bash.
sudo tee
В этом разделе мы будем использовать tee внутри командного режима Vim.
Например, мы отредактируем файл /etc/hosts без sudo.
Затем мы сохраним файл с помощью tee как суперпользователь.
Но прежде всего, что такое tee?
tee
Команда tee одновременно считывает содержимое со стандартного ввода и записывает в стандартный вывод и файлы.
Она позволяет сделать это без использования операторов echo и перенаправления.
В качестве примера добавим текст в файл журнала:
Здесь мы видим, что текст записывается в стандартный вывод, а также в файл baeldung.log.
После добавления текста мы нажимаем Ctrl+C, чтобы сохранить содержимое в файл.
Далее давайте откроем файл:
Теперь вопрос в том, как мы будем использовать tee для сохранения файла в Vim с правами sudo.
Допустим, мы редактируем файл hosts.
Мы можем сохранить его в Vim как sudo:
Давайте разберем это по порядку:
- :w указывает Vim сохранить файл
- !sudo позволяет нам выполнить следующую внешнюю команду с повышенными привилегиями
- tee вызывает команду tee для записи содержимого текущего буфера в файл, указанный %
- % – это специальная переменная Vim, указывающая на имя файла текущего буфера.
В данном контексте tee читает не со стандартного ввода, а из самого файла.
Таким образом, по сути, он записывает содержимое буфера обратно в открытый файл как sudo.
При вводе команды мы должны ввести пароль sudo.
Далее Vim предложит нам перезагрузить файл, так как он был изменен.
Поэтому мы нажимаем L, чтобы перезагрузить файл.
Как только мы нажмем L, файл будет перезагружен.
Кроме того, можно нажать O, чтобы пропустить перезагрузку.
Оговорки
Этот метод хорошо работает для небольших файлов, в именах которых нет пробелов. Однако если у нас есть большие файлы, их содержимое будет записываться как в файл, так и в стандартный вывод, что создаст лишние расходы.
Мало того, если в имени файла есть пробелы или специальные символы, это не будет обработано корректно. К счастью, мы можем справиться с этим с помощью некоторых настроек:
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'В качестве альтернативы мы можем сократить это:
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'Давайте разберем это подробнее:
- sil эффективно подавляет вывод команды
- exec позволяет нам выполнить серию команд
- w !sudo tee записывает содержимое файла как sudo
- . объединяет строки
- shellescape – это функция Vim, которая выполняет эскейп оболочки для текущего имени файла, чтобы обеспечить правильное форматирование
- >/dev/null перенаправляет вывод всей команды на нулевое устройство /dev/null
Кроме того, функция shellescape принимает два аргумента: имя файла и целое число для экранирования специальных символов.
Для имени файла мы использовали @%, чтобы прочитать содержимое регистра %, который содержит путь к текущему буферу.
Второй аргумент – ненулевое целое число (1), чтобы включить обратное экранирование специальных символов.
Хотя эта команда выполняет именно то, что нам нужно, набирать ее может быть утомительно.
Поэтому мы можем написать собственную команду для ее выполнения.
Сопоставление для быстрого сохранения с правами sudo
В наш файл .vimrc добавим команду (W), которая автоматизирует эту задачу:
command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'Кроме того, мы добавим отображение для быстрого сохранения:
map <C-s> :W <CR>
Плагин sudo.vim
sudo.vim – это легкий плагин для Vim, который мы можем использовать для сохранения файла как sudo.
Мы можем скачать и установить его в нашу директорию плагинов.
После установки мы сможем сохранить файл как sudo:
:e sudo:%
Заключение
В этой статье мы узнали, почему невозможно напрямую сохранить файл с правами sudo при редактировании обычным пользователем.
Далее мы использовали команду tee, чтобы найти обходной путь решения проблемы.
Наконец, мы использовали простой плагин Vim в качестве альтернативы команде tee.