Получение root-прав на файл внутри vi? [закрыто]

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

sudo vi filename

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

4.08.2008 03:34:02
возможно просто сохраните копию в вашем домашнем каталоге и "sudo mv" позже
paan 26.08.2008 10:14:23
10 ОТВЕТОВ
РЕШЕНИЕ

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

:w !sudo tee %

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

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

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

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

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

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

292
11.12.2018 23:21:40
Это работает в gvim? При запуске команды Vim запрашивает пароль, но не принимает ввод. Это в конце концов sudo: 1 incorrect password attempt
cmcginty 24.02.2009 03:14:37
я бы не увидел причин, по которым gvim вел себя по-другому ... вы уверены, что sudo само по себе работает правильно?
user3850 24.02.2009 09:58:22
Если вам нужны права суперпользователя для сохранения нового файла, замените% на имя (включая путь) нового файла.
gvkv 10.08.2010 00:47:08
Иногда вам нужно сначала добавить своего пользователя в файл sudoer, ввести пользователя root и открыть /etc/sudoersфайл, добавить его your_username ALL=(ALL) ALLпод строкой root ALL=(ALL) ALL, выйти и сохранить.
coolesting 25.10.2011 03:18:38
@coolesting: 1) вам нужно сделать еще около тысячи вещей ... мы не можем перечислить их все. 2) вы всегда должны использовать visudo.
user3850 26.10.2011 02:33:06

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

:w !sudo tee myfile
32
4.08.2008 06:52:32
:w !sudo tee % >/dev/nullили :w !sudo dd of=%избегайте повторного отображения содержимого файла при сохранении файла.
jamessan 9.12.2009 16:32:33
Можете ли вы объяснить, как это работает? Я поднял голову teeи увидел, что это команда канала Unix, и !вставил команду оболочки. Является ли :wнаписание к стандарту, который получает по каналу tee?
Eric Hu 10.09.2012 19:37:22
@ Эрик, все верно. команда "tee myfile" скопирует стандартный ввод в myfile. запуск «sudo tee myfile» будет делать то же самое, но поскольку процесс tee принадлежит root, myfile также будет принадлежать root. На стороне vi, ": w! Some command line" передаст все строки в "некоторую командную строку".
Mark Harrison 10.09.2012 23:15:43

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

Наиболее распространенный способ обойти проблему файла, доступного только для чтения, - открыть канал для текущего файла в качестве суперпользователя, используя реализацию 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трубы 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
16
13.10.2012 06:54:18
Что если вы отключите Windows, фактически создав файл с возможностью записи для всего мира в C: \ dev \ null?
Paul Stelian 6.07.2016 14:23:08
@PaulStelian Возможно, но вряд ли. Вы можете легко расширить этот код для учета различных платформ и обстоятельств. В действительности, вы вряд ли столкнетесь с ситуацией в Windows, где она sudoсуществует, но ее нет /dev/null, поэтому вам нужно быть более изощренной, если вы хотите настоящую кроссплатформенную поддержку. Это скорее вступление - пища для размышлений. :)
Zenexer 6.07.2016 16:44:13

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

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

11
20.12.2016 07:22:36
Я бы не рекомендовал использовать этот скрипт, так как он не принимает надлежащих мер предосторожности при экранировании имен файлов.
jamessan 9.12.2009 16:31:28

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

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

7
4.08.2008 04:04:52

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

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

3
15.11.2008 06:49:03
cat $ tmp> $ target - креатив, но есть ли причина не просто sudo mv файл?
ojrac 14.11.2008 20:56:54
Хороший вопрос. Была также большая проблема с sudo cat что-то> / etc / blah - он будет использовать sudo для cat файла, а затем обычный пользователь для записи в / etc / blah (что не будет работать). Исправлено в ответ, и добавил ваш лучший Судо мВ предложение ..
dbr 15.11.2008 06:50:16
Предложение mv не сохраняет разрешения.
Paul Stelian 6.07.2016 14:24:20

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

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

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

1
4.08.2008 03:39:31

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

1
29.01.2010 17:21:29

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

alias svim='sudo vim'

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

0
19.03.2009 12:51:48
Команда sudoeditдолжна быть предпочтительной, поскольку она не требует запуска vim от имени пользователя root.
jamessan 9.12.2009 16:30:37
Это по-прежнему не останавливает вас, связывая vim вместо svim, к которому ОП прибегает.
ScaryAardvark 4.02.2010 13:52:42
-1, это просто говорит «не забывайте вводить sudo при открытии файла», OP хочет знать, как они могут получить привилегии root в vi.
Brad Koch 27.02.2013 16:57:00

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

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

-2
5.08.2008 22:20:58