Uzyskanie uprawnień roota na pliku wewnątrz vi?

Często podczas edytowania plików konfiguracyjnych otwieram jeden z vi i kiedy idę go zapisać uświadamiam sobie, że nie wpisałem

sudo vi filename

Czy Jest jakiś sposób na nadanie VI sudo uprawnień do zapisania pliku? Wydaje mi się, że widziałem coś o tym, gdy szukałem czegoś o vi jakiś czas temu, ale teraz nie mogę go znaleźć.

 231
Author: Paul Wicks, 2008-08-04

11 answers

% jest zamieniona na bieżącą nazwę pliku, więc możesz użyć:

:w !sudo tee %

(vim wykryje, że plik został zmieniony i zapyta, czy chcesz go ponownie załadować.)

Jako skrót możesz zdefiniować własne polecenie. Umieść w swoim .vimrc:

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

Z powyższego możesz wpisać :W<Enter>, aby zapisać plik. Od kiedy to napisałem, znalazłem ładniejszy sposób (moim zdaniem), aby to zrobić:

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

W ten sposób możesz wpisać :w!! i zostanie ona rozszerzona do pełna linia poleceń, pozostawiając kursor na końcu, więc możesz zastąpić % własną nazwą pliku, jeśli chcesz.

 279
Author: Lai Jiangshan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-14 09:15:27

Ogólnie rzecz biorąc, nie można zmienić efektywnego identyfikatora użytkownika procesu vi, ale można to zrobić:

:w !sudo tee myfile
 30
Author: Mark Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-04 06:52:32

Wspólne Zastrzeżenie

Najczęstszą metodą obejścia problemu z plikiem tylko do odczytu jest otwarcie potoku do bieżącego pliku jako super-Użytkownik przy użyciu implementacji sudo tee. Jednak wszystkie najpopularniejsze rozwiązania, które znalazłem w Internecie, mają kombinację kilku potencjalnych zastrzeżeń: [41]}

  • cały plik jest zapisywany do terminala, podobnie jak plik. Może to być powolne w przypadku dużych plików, szczególnie w powolnej sieci znajomości.
  • plik traci swoje tryby i podobne atrybuty.
  • ścieżki plików z nietypowymi znakami lub spacjami mogą nie być obsługiwane poprawnie.

Rozwiązania

Aby obejść wszystkie te problemy, możesz użyć następującego polecenia:

" 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'

Można je skrócić, z szacunkiem:

:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'

Wyjaśnienie

: rozpoczyna polecenie; będziesz musiał wpisać ten znak w trybie normalnym, aby rozpocząć wprowadzanie polecenia. Powinno być pominięte w skryptach.

sil[ent] wyłącza wyjście z polecenia. W tym przypadku chcemy zatrzymać znak zachęty podobny do znaku Press any key to continue, który pojawia się po uruchomieniu polecenia :!.

exec[ute] wykonuje ciąg znaków jako polecenie. Nie możemy po prostu uruchomić :write, ponieważ nie przetworzy ona wymaganego wywołania funkcji.

! reprezentuje polecenie :!: jedyne polecenie, które :write akceptuje. Zwykle :write akceptuje ścieżkę do pliku, do której ma być zapisany. :! samodzielnie uruchamia polecenie w powłoce (dla przykład, używając bash -c). Z :write, uruchomi polecenie w powłoce, a następnie zapisze cały plik do stdin.

sudo to powinno być oczywiste, bo po to tu jesteś. Uruchom polecenie jako super-użytkownik. W sieci jest mnóstwo informacji o tym, jak to działa.

tee rury stdin do podanego pliku. :write zapisze do stdin, następnie super-użytkownik tee otrzyma zawartość pliku i zapisze plik. Nie utworzy nowego pliku - wystarczy nadpisać zawartość -- so tryby i atrybuty plików zostaną zachowane.

shellescape() usuwa znaki specjalne w podanej ścieżce pliku, odpowiednio dla bieżącej powłoki. Mając tylko jeden parametr, Zwykle ujmuje ścieżkę w cudzysłowie w razie potrzeby. Ponieważ wysyłamy do pełnego wiersza poleceń powłoki, będziemy chcieli przekazać niezerową wartość jako drugi argument, aby włączyć odwrotne ukośniki-ucieczki innych znaków specjalnych, które w przeciwnym razie mogłyby potknąć się o powłokę.

@% czyta zawartość rejestru %, który zawiera nazwę pliku bieżącego bufora. Niekoniecznie jest to ścieżka bezwzględna, więc upewnij się, że nie zmieniłeś bieżącego katalogu. W niektórych rozwiązaniach pojawia się symbol commercial-at pominięty. W zależności od lokalizacji, % jest poprawnym wyrażeniem i ma taki sam efekt jak odczyt rejestru %. Zagnieżdżony w innym wyrażeniu skrót jest jednak na ogół niedozwolony: na przykład w tym przypadku.

>NUL i >/dev/null przekierowanie stdout do urządzenia null platformy. Mimo że wyciszyliśmy polecenie, nie chcemy, aby wszystkie napowietrzne elementy związane z orurowaniem stdin wróciły do Vima-najlepiej zrzucić je JAK NAJSZYBCIEJ. NUL jest urządzeniem null w systemach DOS, MS-DOS i Windows, a nie prawidłowym plikiem. W systemie Windows 8 przekierowania do NUL nie skutkują zapisaniem pliku o nazwie NUL. Spróbuj utworzyć na pulpicie plik o nazwie NUL, z rozszerzeniem lub bez: nie będziesz w stanie tego zrobić. (Istnieje kilka innych nazwy urządzeń w systemie Windows, które warto poznać.)

~/.vimrc

Zależne Od Platformy

Oczywiście nadal nie chcesz ich zapamiętać i wpisywać za każdym razem. O wiele łatwiej jest odwzorować odpowiednie polecenie na prostsze polecenie użytkownika. Aby to zrobić w POSIX, możesz dodać następującą linię do pliku ~/.vimrc, tworząc go, jeśli jeszcze nie istnieje:
command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'

To pozwoli Ci wpisać polecenie: W (rozróżnia wielkość liter), aby zapisać bieżący plik z uprawnieniami super-user--dużo łatwiej.

Niezależny Od Platformy

Używam niezależnego od platformy pliku ~/.vimrc, który synchronizuje się między komputerami, więc dodałem funkcjonalność wieloplatformową do mojego. Oto ~/.vimrc Z tylko odpowiednimi ustawieniami:

#!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
 14
Author: Zenexer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-13 06:54:18

Jeśli używasz Vim , dostępny jest skrypt o nazwie sudo.vim . Jeśli odkryjesz, że otworzyłeś plik, do którego odczytu potrzebujesz dostępu roota, wpisz

:e sudo:%
Vim zastępuje % nazwą bieżącego pliku, a sudo: instruuje sudo.skrypt vim do przejęcia do czytania i pisania.
 10
Author: ephemient,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-20 07:22:36

Rada Ryana jest ogólnie dobra, jednak jeśli wykonasz Krok 3, nie przenoś pliku tymczasowego; będzie miał złe prawa własności i uprawnienia. Zamiast tego sudoedit poprawny plik i odczytany w treści (używając :r lub podobnych) pliku tymczasowego.

Jeśli wykonasz Krok 2, Użyj :w!, aby wymusić zapisanie pliku.

 7
Author: Chris Jester-Young,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-04 04:04:52

Gdy wejdziesz w tryb wstawiania na pliku, który potrzebujesz sudo access do edycji, otrzymasz komunikat o statusie:

-- INSERT -- W10: Warning: Changing a readonly file

Jeśli za tym tęsknię, generalnie to robię

:w ~/edited_blah.tmp
:q

..więc..

sudo "cat edited_blah.tmp > /etc/blah"

..albo..

sudo mv edited_blah.tmp /etc/blah
Prawdopodobnie jest mniej okrężny sposób, ale to działa.
 3
Author: dbr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-15 06:49:03

Szybkie Google daje takie rady:

  1. nie próbuj edytować, jeśli jest tylko do odczytu.
  2. możesz zmienić uprawnienia do pliku. (To, czy pozwoli Ci zaoszczędzić, zależy od eksperymentów.)
  3. jeśli i tak nadal edytujesz, Zapisz do pliku tymczasowego, a następnie przenieś go.

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

 1
Author: Ryan Fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-04 03:39:31

Oto kolejny, który pojawił się od odpowiedzi na to pytanie, plugin o nazwie SudoEdit, który udostępnia funkcje SudoRead i SudoWrite, które domyślnie spróbują użyć sudo jako pierwszego i su, jeśli to się nie powiedzie: http://www.vim.org/scripts/script.php?script_id=2709

 1
Author: James Snyder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-29 17:21:29

Mam to w moim~/.bashrc:

alias svim='sudo vim'

Teraz, gdy muszę edytować plik konfiguracyjny, otwieram go za pomocą svim.

 0
Author: pisswillis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-19 12:51:48

Szybki hack, który możesz rozważyć, to wykonanie chmod na edytowanym pliku, zapisanie za pomocą Vima, a następnie chmod z powrotem do tego, co plik był pierwotnie.

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)

Oczywiście nie polecam takiego podejścia w systemie, w którym martwisz się o bezpieczeństwo, ponieważ przez kilka sekund każdy może odczytać/zmienić plik bez Twojej wiedzy.

 -2
Author: num1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-05 22:20:58

Użycie gksudo zamiast sudo dla GVim czyli

cmap w!! w !gksudo tee >/dev/null %
 -7
Author: ryfm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-30 06:33:11