Как работает `: w! Sudo tee%`

27

Если вы откроете файл, на который у вас нет разрешения на запись в vim, то решите, что вам нужно его изменить, вы можете записать свои изменения, не выходя из vim, выполнив « :w !sudo tee %
Я не понимаю, как это может работать». Не могли бы вы проанализировать это?
Я понимаю :wчасть, он записывает текущий буфер на диск, предполагая, что с ним уже связано имя файла, верно?
Я также понимаю, !что выполняет sudo teeкоманду и %представляет текущее содержимое буфера правильно?
Но все еще не понимаю, как это работает.

Али
источник

Ответы:

30

Структурные :w !cmdсредства «написать текущий буфер поступает через команду». Например, вы можете сделать это, :w !catи он пропустит буфер cat.

Теперь %это имя файла , связанный с буфером

Таким образом, :w !sudo tee %будет проходить содержимое буфера sudo tee FILENAME. Это эффективно записывает содержимое буфера в файл.

Стивен Харрис
источник
А что есть tee?
CodyBugstein
7

% представляет имя файла текущего буфера, а не его содержимое.

значит :w !sudo tee %означает передать текущий буфер в sudo tee [currentfilename].

tee запускается от имени пользователя root, поэтому имеет право на запись для сохранения своего стандартного файла в файл.

Смотрите также /programming/2600783/how-does-the-vim-write-with-sudo-trick-work

саз
источник
2

Не совсем верно!

!commandзапускает команду как команду фильтра , которая получает текст stdin, что-то делает и выводит в stdout.

Используя w, вы передали содержимое файла в stdinоф sudo tee %. %это специальный регистр в vim, который содержит имя текущего файла.

Таким образом, вы получили sudo tee FILENAME, что подтолкнет tee stdin- файл содержимого - в текущий файл.

cuonglm
источник
2
:!commandэто фильтр (ср. :h !), а :w !commandнет, он просто выполняется commandс текущим файлом как stdin(ср. :h :w_c). То есть: :w !sed /./dне меняет содержимое текущего буфера. Но рецепт действительно не совсем верный по другой причине, его %нужно избегать :exec 'w !sudo tee ' . shellescape(expand('%', 1)). Исходная команда не работает, скажем, с именами файлов с пробелами.
Satō Katsura