Wie speichere ich eine Datei, für die ich keine Schreibrechte habe?

26

Es kommt manchmal vor, dass ich eine Datei öffne und einige Änderungen als mein eigener Benutzer vornehme, ohne die [read-only]Warnung in der Statuszeile zu bemerken oder zu "vergessen" (zB eine zufällige /etcKonfigurationsdatei wie /etc/resolv.conf).

:w!offensichtlich scheitert in diesem Fall, weil mein Benutzer ohnehin keine Schreibberechtigung hat. Also muss ich :w /home/filenameraus und sudo mv ..., sehr unangenehm.

Gibt es eine Möglichkeit, dass ich vorübergehend zu root eskaliere, um die aktuell geöffnete Datei speichern zu können? (vorausgesetzt ich bin in sudoersoder / und ich kann sudirekt)?

Guido
quelle

Antworten:

24

Der Trick besteht darin, einen externen Anruf zu verwenden, um sudo:

:w !sudo tee %

Wie das funktioniert:

  • :w !<command>Wird <command>mit dem Inhalt des Puffers als stdin ausgeführt.
  • teedupliziert stdin in eine Datei & stdout; %wird auf den aktuellen Dateinamen erweitert.
  • Sie stellen dies als Präfix sudofür Root-Berechtigungen ein.

Sie speichern die Datei nicht wirklich mit Vim, sondern rufen ein externes Programm auf, um den Inhalt der Datei, die Sie bearbeiten, zu überschreiben. Aus diesem Grund erhalten Sie eine Warnung von Vim:

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: 

Sie könnten dies in eine Funktion verwandeln:

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

Und keybind:

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

Mit sukann nur der Root-Benutzer -ceinen Befehl sofort ausführen. Ich glaube nicht, dass Sie das gebrauchen sukönnen, aber vielleicht gibt es einen Trick, den ich nicht kenne ...

Martin Tournoij
quelle
SuperWritefunktioniert, gibt aber die Datei an Sie zurück. :silentWenn Sie es laufen lassen, müssen Sie Ihr Passwort unsichtbar eingeben.
TankorSmash
@TankorSmash Danke; aktualisierte Antwort. Nicht sicher, was Sie mit "Passwort unsichtbar eingeben" meinen? Hinzufügen silentscheint gut zu funktionieren?
Martin Tournoij
Ich führe vim nicht mit sudo aus, so dass dies hier möglicherweise im Spiel ist, aber wenn ich zum sudo tee der Datei gehe, werde ich zur Eingabe des sudo-Passworts aufgefordert. Wenn es still ist, wird die Aufforderung nicht angezeigt, es muss jedoch noch ein Kennwort eingegeben werden.
TankorSmash
1
Was Sie sehen, ist die Standardfunktionalität von tee, sowohl die Ausgabe als auch die angegebene Datei. Eine Lösung besteht darin, stdout nach / dev / null umzuleiten, a la: w ! tee % > /dev/null Dies gibt weiterhin das Ergebnis des Befehls (eine einzelne Zeile) wieder, jedoch nicht den gesamten Pufferinhalt.
Jon Carter
teeWürde es nicht catauch funktionieren, wenn Sie nicht möchten, dass die Datei ausgedruckt wird, anstatt die Ausgabe zu verwenden und dann wegzuwerfen ?
Lie Ryan
12

Ich verwende die folgende Zuordnung in meiner .vimrc, die ich nützlich finde:

cnoremap w!! w !sudo tee %

Es ist leicht zu merken, weil wes "Schreiben" w!ist, "Force Write" ist und w!!"Super-Duper-Force Write" ist. : P

Türknauf
quelle
1
Ich habe es schon lange zugeordnet W, aber es w!!ist viel sinnvoller, meine .vimrc zu aktualisieren. Vielen Dank
Jalanb