Frage

Beim Bearbeiten von Konfigurationsdateien öffne ich oft eine mit vi und stelle dann beim Speichern fest, dass ich nichts eingegeben habe

sudo vi filename

Gibt es eine Möglichkeit, vi Sudo-Berechtigungen zum Speichern der Datei zu erteilen?Ich erinnere mich, dass ich vor einiger Zeit etwas dazu gesehen habe, als ich nach etwas über vi gesucht habe, aber jetzt kann ich es nicht finden.

War es hilfreich?

Lösung

% wird durch den aktuellen Dateinamen ersetzt, Sie können also Folgendes verwenden:

:w !sudo tee %

(vim erkennt, dass die Datei geändert wurde und fragt, ob Sie sie neu laden möchten.Sagen Sie Ja, indem Sie wählen [L] statt OK.)

Als Verknüpfung können Sie Ihren eigenen Befehl definieren.Tragen Sie Folgendes in Ihr ein .vimrc:

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

Mit dem Obigen können Sie tippen :W<Enter> um die Datei zu speichern.Seitdem ich das geschrieben habe, habe ich (meiner Meinung nach) einen schöneren Weg gefunden, dies zu tun:

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

Auf diese Weise können Sie tippen :w!! und es wird auf die vollständige Befehlszeile erweitert, wobei der Cursor am Ende verbleibt, sodass Sie das ersetzen können % mit einem eigenen Dateinamen, wenn Sie möchten.

Andere Tipps

Im Allgemeinen können Sie die effektive Benutzer-ID des vi-Prozesses nicht ändern, aber Sie können Folgendes tun:

:w !sudo tee myfile

Allgemeine Vorsichtsmaßnahmen

Die gebräuchlichste Methode, das Problem der schreibgeschützten Datei zu umgehen, besteht darin, als Superuser mithilfe einer Implementierung von eine Pipe zur aktuellen Datei zu öffnen sudo tee.Allerdings weisen alle beliebtesten Lösungen, die ich im Internet gefunden habe, eine Kombination mehrerer potenzieller Einschränkungen auf:

  • Die gesamte Datei wird auf das Terminal geschrieben, ebenso wie die Datei.Dies kann bei großen Dateien langsam sein, insbesondere bei langsamen Netzwerkverbindungen.
  • Die Datei verliert ihre Modi und ähnliche Attribute.
  • Dateipfade mit ungewöhnlichen Zeichen oder Leerzeichen werden möglicherweise nicht korrekt verarbeitet.

Lösungen

Um all diese Probleme zu umgehen, können Sie den folgenden Befehl verwenden:

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

Diese können respektvoll gekürzt werden:

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

Erläuterung

: beginnt den Befehl;Sie müssen dieses Zeichen im normalen Modus eingeben, um mit der Eingabe eines Befehls zu beginnen.Es sollte in Skripten weggelassen werden.

sil[ent] unterdrückt die Ausgabe des Befehls.In diesem Fall wollen wir das stoppen Press any key to continue-ähnliche Eingabeaufforderung, die nach dem Ausführen von angezeigt wird :! Befehl.

exec[ute] führt einen String als Befehl aus.Wir können nicht einfach rennen :write weil der erforderliche Funktionsaufruf nicht verarbeitet wird.

! repräsentiert die :! Befehl:der einzige Befehl, der :write akzeptiert.Normalerweise, :write akzeptiert einen Dateipfad, in den geschrieben werden soll. :! führt allein einen Befehl in einer Shell aus (z. B. using bash -c).Mit :write, führt es den Befehl in der Shell aus und schreibt dann die gesamte Datei hinein stdin.

sudo sollte klar sein, denn deshalb sind Sie hier.Führen Sie den Befehl als Superuser aus.Im Internet gibt es zahlreiche Informationen darüber, wie das funktioniert.

tee Rohre stdin zur angegebenen Datei. :write Werde anschreiben stdin, dann der Superuser tee empfängt den Dateiinhalt und schreibt die Datei.Es wird keine neue Datei erstellt, sondern nur der Inhalt überschrieben, sodass die Dateimodi und -attribute erhalten bleiben.

shellescape() maskiert Sonderzeichen im angegebenen Dateipfad entsprechend der aktuellen Shell.Bei nur einem Parameter wird der Pfad normalerweise nur bei Bedarf in Anführungszeichen gesetzt.Da wir an eine vollständige Shell-Befehlszeile senden, möchten wir als zweites Argument einen Wert ungleich Null übergeben, um das Backslash-Escape anderer Sonderzeichen zu ermöglichen, die andernfalls die Shell zum Absturz bringen könnten.

@% liest den Inhalt der % Register, das den Dateinamen des aktuellen Puffers enthält.Es handelt sich nicht unbedingt um einen absoluten Pfad. Stellen Sie daher sicher, dass Sie das aktuelle Verzeichnis nicht geändert haben.In einigen Lösungen wird das Commercial-at-Symbol weggelassen.Je nach Standort, % ist ein gültiger Ausdruck und hat die gleiche Wirkung wie das Lesen von % registrieren.In einem anderen Ausdruck verschachtelt ist die Verknüpfung im Allgemeinen jedoch nicht zulässig:wie in diesem Fall.

>NUL Und >/dev/null umleiten stdout zum Nullgerät der Plattform.Obwohl wir den Befehl zum Schweigen gebracht haben, möchten wir nicht den gesamten mit der Weiterleitung verbundenen Aufwand verursachen stdin Zurück zu vim – es ist am besten, es so früh wie möglich zu löschen. NUL ist das Nullgerät unter DOS, MS-DOS und Windows, keine gültige Datei.Ab Windows 8 führen Umleitungen zu NUL nicht dazu, dass eine Datei mit dem Namen NUL geschrieben wird.Versuchen Sie, auf Ihrem Desktop eine Datei mit dem Namen NUL zu erstellen, mit oder ohne Dateierweiterung:Sie werden dazu nicht in der Lage sein.(Es gibt mehrere andere Gerätenamen in Windows, die es wert sein könnten, sie kennenzulernen.)

~/.vimrc

Plattformabhängig

Natürlich möchten Sie diese trotzdem nicht auswendig lernen und jedes Mal abtippen.Es ist viel einfacher, den entsprechenden Befehl einem einfacheren Benutzerbefehl zuzuordnen.Um dies unter POSIX zu tun, können Sie die folgende Zeile zu Ihrem hinzufügen ~/.vimrc Datei, erstellen Sie sie, falls sie noch nicht vorhanden ist:

command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'

Dadurch können Sie den Befehl :W (Groß-/Kleinschreibung beachten) eingeben, um die aktuelle Datei mit Superuser-Berechtigungen zu schreiben – was viel einfacher ist.

Plattformunabhängig

Ich verwende eine plattformunabhängige ~/.vimrc Datei, die computerübergreifend synchronisiert wird, daher habe ich meine um Multiplattform-Funktionalität erweitert.Hier ist ein ~/.vimrc mit nur den relevanten Einstellungen:

#!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

Wenn Sie verwenden Vim, es ist ein Skript mit dem Namen verfügbar sudo.vim.Wenn Sie feststellen, dass Sie eine Datei geöffnet haben, für deren Lesen Sie Root-Zugriff benötigen, geben Sie Folgendes ein

:e sudo:%
Vim ersetzt % durch den Namen der aktuellen Datei und sudo: weist das Skript sudo.vim an, das Lesen und Schreiben zu übernehmen.

Ryans Rat ist im Allgemeinen gut. Wenn Sie jedoch Schritt 3 befolgen, verschieben Sie die temporäre Datei nicht.Es wird den falschen Besitz und die falschen Berechtigungen haben.Stattdessen, sudoedit die richtige Datei und lesen Sie den Inhalt ein (mit :r oder Ähnliches) der temporären Datei.

Wenn Sie Schritt 2 befolgen, verwenden Sie :w! um das Schreiben der Datei zu erzwingen.

Wenn Sie für eine Datei, für deren Bearbeitung Sie Sudo-Zugriff benötigen, in den Einfügemodus wechseln, erhalten Sie die Statusmeldung „

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

Wenn ich das vermisse, tue ich es im Allgemeinen

:w ~/edited_blah.tmp
:q

..Dann..

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

..oder..

sudo mv edited_blah.tmp /etc/blah

Es gibt wahrscheinlich einen weniger umständlichen Weg, aber es funktioniert.

Ein kurzer Google scheint diesen Rat zu geben:

  1. Versuchen Sie nicht, die Datei zu bearbeiten, wenn sie schreibgeschützt ist.
  2. Möglicherweise können Sie die Berechtigungen für die Datei ändern.(Ob Sie damit sparen können, bleibt dem Experiment überlassen.)
  3. Wenn Sie trotzdem etwas bearbeitet haben, speichern Sie es in einer temporären Datei und verschieben Sie sie dann.

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

Hier ist ein weiteres Plugin, das seit der Beantwortung dieser Frage aufgetaucht ist, ein Plugin namens SudoEdit, das die Funktionen SudoRead und SudoWrite bereitstellt, die standardmäßig versuchen, zuerst sudo und su zu verwenden, wenn dies fehlschlägt: http://www.vim.org/scripts/script.php?script_id=2709

Ich habe das in meinem ~/.bashrc:

alias svim='sudo vim'

Wenn ich jetzt eine Konfigurationsdatei bearbeiten muss, öffne ich sie einfach mit svim.

Ein schneller Hack, den Sie in Betracht ziehen können, besteht darin, ein chmod für die Datei, die Sie bearbeiten, auszuführen, mit vim zu speichern und dann chmod auf den ursprünglichen Zustand der Datei zurückzusetzen.

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)

Natürlich empfehle ich diesen Ansatz nicht in einem System, in dem Sie sich Sorgen um die Sicherheit machen, da für ein paar Sekunden jeder die Datei lesen/ändern kann, ohne dass Sie es merken.

verwenden gksudo anstatt Sudo für GVim d.h.

cmap w!! w !gksudo tee >/dev/null %
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top