Jak zapisać plik, dla którego nie mam uprawnień do zapisu?

26

Czasami zdarza się, że otwieram plik i wprowadzam pewne modyfikacje jako mój użytkownik, nie zauważając ani nie zapominając o zauważeniu [read-only]ostrzeżenia w wierszu stanu (np. Jakiś losowy /etcplik konfiguracyjny, taki jak /etc/resolv.conf).

:w!oczywiście kończy się niepowodzeniem w tym przypadku, ponieważ mój użytkownik i tak nie ma uprawnień do zapisu. Więc muszę :w /home/filenamewyjść i sudo mv ...bardzo niewygodnie.

Czy jest jakiś sposób, żebym tymczasowo eskalował do roota, aby móc zapisać aktualnie otwarty plik? (pod warunkiem, że jestem w sudoers/ i mogę subezpośrednio)?

guido
źródło

Odpowiedzi:

24

Sztuką jest użycie połączenia zewnętrznego, aby sudo:

:w !sudo tee %

Jak to działa:

  • :w !<command>wykonuje się <command>z zawartością bufora jako stdin.
  • teeduplikuje standardowe wejście do pliku & standardowe wyjście; %rozwija się do bieżącej nazwy pliku ..
  • Przedrostek ten podajesz sudodla uprawnień roota.

Nie jesteś naprawdę zapisując plik z vim raczej dzwonisz zewnętrznego programu do zastąpienia zawartości pliku, który edytujesz. Oto dlaczego otrzymasz ostrzeżenie od Vima:

W12: Warning: File "xxx" has changed and the buffer was changed in Vim as well
See ":help W12" for more info.
[O]K, (L)oad File: 

Możesz zmienić to w funkcję:

fun! SuperWrite()
        write !sudo tee %
        " Or with :silent (but that doesn't seem to work for everyone)
        "silent write !sudo tee %
        edit!
endfun

I keybind:

nnoremap <Leader>w! :call SuperWrite()<CR>

Za pomocą sutylko użytkownik root może -cnatychmiast wykonać polecenie. Nie sądzę, że możesz tego użyć su, ale być może istnieje pewien sposób, którego nie znam ...

Martin Tournoij
źródło
SuperWritedziała, ale ponownie wyświetla plik w tobie. Uruchomienie go :silentspowoduje, że hasło zostanie wprowadzone niewidocznie.
TankorSmash
@TankorSmash Thanks; zaktualizowana odpowiedź. Nie jesteś jednak pewien, co masz na myśli przez „niewidoczne wprowadzenie hasła”? silentWydaje się, że dodawanie działa dobrze?
Martin Tournoij
Nie uruchamiam vima z sudo, więc może tu być gra, ale kiedy idę do sudo tee plik, monituje mnie o hasło sudo. Jeśli jest cichy, nie widzę monitu, ale nadal muszę wprowadzić hasło.
TankorSmash
1
To, co widzisz, to standardowa funkcja tee wysyłania echa na standardowe wyjście, a także podany plik. Rozwiązaniem jest przekierowanie stdout do / dev / null, la: w ! tee % > /dev/null To nadal będzie odzwierciedlać wynik polecenia (pojedyncza linia), ale nie całą zawartość bufora.
Jon Carter
Zamiast używania teei wyrzucania danych wyjściowych, nie catdziałałoby również, jeśli nie chcesz wydrukować pliku?
Lie Ryan,
12

Korzystam z następującego mapowania w moim .vimrc, które uważam za przydatne:

cnoremap w!! w !sudo tee %

Łatwo to zapamiętać, ponieważ wjest to „pisać”, w!jest „wymuszać zapisywanie” i w!!„super-duper-wymusza zapisywanie”. : P

Klamka
źródło
1
Od dawna mam to zmapowane W, ale w!!ma o wiele więcej sensu, zaktualizuję mój .vimrc. Dzięki
jalanb