Domanda

Spesso mentre modifico i file di configurazione, ne apro uno con vi e poi quando vado a salvarlo mi accorgo che non ho digitato

sudo vi filename

Esiste un modo per concedere i privilegi di vi sudo per salvare il file?Mi sembra di ricordare di aver visto qualcosa a riguardo mentre cercavo alcune cose su vi qualche tempo fa, ma ora non riesco a trovarlo.

È stato utile?

Soluzione

% viene sostituito con il nome del file corrente, quindi puoi utilizzare:

:w !sudo tee %

(vim rileverà che il file è stato modificato e ti chiederà se desideri che venga ricaricato.Di' sì scegliendo [L] piuttosto che OK.)

Come scorciatoia, puoi definire il tuo comando.Inserisci quanto segue nel tuo .vimrc:

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

Con quanto sopra puoi digitare :W<Enter> per salvare il file.Da quando ho scritto questo, ho trovato un modo più carino (secondo me) per farlo:

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

In questo modo puoi digitare :w!! e verrà espanso per l'intera riga di comando, lasciando il cursore alla fine, in modo da poter sostituire il file % con un nome file personalizzato, se lo desideri.

Altri suggerimenti

In generale, non puoi modificare l'ID utente effettivo del processo vi, ma puoi farlo:

:w !sudo tee myfile

Avvertenze comuni

Il metodo più comune per aggirare il problema del file di sola lettura è aprire una pipe al file corrente come superutente utilizzando un'implementazione di sudo tee.Tuttavia, tutte le soluzioni più popolari che ho trovato su Internet presentano una combinazione di diversi potenziali avvertimenti:

  • L'intero file viene scritto sul terminale, così come il file.Questo può essere lento per file di grandi dimensioni, soprattutto su connessioni di rete lente.
  • Il file perde le sue modalità e attributi simili.
  • I percorsi dei file con caratteri o spazi insoliti potrebbero non essere gestiti correttamente.

Soluzioni

Per aggirare tutti questi problemi, è possibile utilizzare il seguente comando:

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

Questi possono essere abbreviati, rispettosamente:

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

Spiegazione

: inizia il comando;dovrai digitare questo carattere in modalità normale per iniziare a inserire un comando.Dovrebbe essere omesso negli script.

sil[ent] sopprime l'output del comando.In questo caso, vogliamo interrompere il Press any key to continue-like che appare dopo aver eseguito il file :! comando.

exec[ute] esegue una stringa come comando.Non possiamo semplicemente scappare :write perché non elaborerà la chiamata di funzione necessaria.

! rappresenta il :! comando:l'unico comando che :write accetta.Normalmente, :write accetta un percorso di file su cui scrivere. :! da solo esegue un comando in una shell (ad esempio, using bash -c).Con :write, eseguirà il comando nella shell e quindi scriverà l'intero file stdin.

sudo dovrebbe essere ovvio, visto che è per questo che sei qui.Esegui il comando come superutente.Ci sono moltissime informazioni in rete su come funziona.

tee tubi stdin al file specificato. :write scriverò a stdin, quindi il superutente tee riceverà il contenuto del file e scriverà il file.Non creerà un nuovo file, ne sovrascriverà semplicemente il contenuto, quindi le modalità e gli attributi del file verranno preservati.

shellescape() esegue l'escape dei caratteri speciali nel percorso del file specificato in modo appropriato per la shell corrente.Con un solo parametro, in genere racchiude semplicemente il percorso tra virgolette, se necessario.Poiché stiamo inviando a una riga di comando della shell completa, vorremo passare un valore diverso da zero come secondo argomento per abilitare l'escape con barra rovesciata di altri caratteri speciali che potrebbero altrimenti far inciampare la shell.

@% legge il contenuto del % registro, che contiene il nome del file del buffer corrente.Non è necessariamente un percorso assoluto, quindi assicurati di non aver modificato la directory corrente.In alcune soluzioni, vedrai il simbolo commerciale omesso.A seconda della posizione, % è un'espressione valida e ha lo stesso effetto della lettura del file % Registrati.Nidificata all'interno di un'altra espressione, la scorciatoia generalmente non è consentita, tuttavia:come in questo caso.

>NUL E >/dev/null reindirizzare stdout al dispositivo nullo della piattaforma.Anche se abbiamo silenziato il comando, non vogliamo tutto il sovraccarico associato alle tubazioni stdin torniamo a Vim: è meglio scaricarlo il prima possibile. NUL è il dispositivo nullo su DOS, MS-DOS e Windows, non un file valido.A partire da Windows 8 i reindirizzamenti a NUL non comportano la scrittura di un file denominato NUL.Prova a creare un file sul desktop denominato NUL, con o senza estensione di file:non sarai in grado di farlo.(Ci sono molti altri nomi di dispositivi in ​​Windows che potrebbe valere la pena conoscere.)

~/.vimrc

Dipendente dalla piattaforma

Naturalmente, non vuoi ancora memorizzarli e digitarli ogni volta.È molto più semplice associare il comando appropriato a un comando utente più semplice.Per fare ciò su POSIX, potresti aggiungere la seguente riga al tuo ~/.vimrc file, creandolo se non esiste già:

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

Ciò ti consentirà di digitare il comando :W (con distinzione tra maiuscole e minuscole) per scrivere il file corrente con autorizzazioni da superutente: molto più semplice.

Piattaforma indipendente

Io uso un indipendente dalla piattaforma ~/.vimrc file che si sincronizza su più computer, quindi ho aggiunto la funzionalità multipiattaforma al mio.Ecco un ~/.vimrc con solo le impostazioni pertinenti:

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

Se stai usando Vim, è disponibile uno script denominato sudo.vim.Se scopri di aver aperto un file per cui hai bisogno dell'accesso root per leggere, digita

:e sudo:%
Vim sostituisce % con il nome del file corrente e sudo: indica allo script sudo.vim di assumere il controllo della lettura e della scrittura.

Il consiglio di Ryan è generalmente buono, tuttavia, se si segue il passaggio 3, non spostare il file temporaneo;avrà proprietà e autorizzazioni errate.Invece, sudoedit il file corretto e leggerne il contenuto (utilizzando :r o simili) del file temporaneo.

Se si segue il passaggio 2, utilizzare :w! per forzare la scrittura del file.

Quando entri in modalità di inserimento su un file di cui hai bisogno sudo access per modificarlo, ricevi un messaggio di stato che dice

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

Se mi manca, generalmente lo faccio

:w ~/edited_blah.tmp
:q

..Poi..

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

..O..

sudo mv edited_blah.tmp /etc/blah

Probabilmente c'è un modo meno indiretto per farlo, ma funziona.

Un rapido Google sembra dare questo consiglio:

  1. Non provare a modificare se è di sola lettura.
  2. Potresti essere in grado di modificare le autorizzazioni sul file.(Se ti consentirà o meno di salvare dipende dalla sperimentazione.)
  3. Se hai comunque apportato modifiche, salva in un file temporaneo e quindi spostalo.

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

Eccone un altro che è apparso da quando è stata data risposta a questa domanda, un plugin chiamato SudoEdit che fornisce le funzioni SudoRead e SudoWrite, che per impostazione predefinita proveranno a utilizzare prima sudo e su se falliscono: http://www.vim.org/scripts/script.php?script_id=2709

Ho questo nel mio ~/.bashrc:

alias svim='sudo vim'

Ora ogni volta che devo modificare un file di configurazione, lo apro semplicemente con svim.

Un trucco veloce che puoi prendere in considerazione è eseguire un chmod sul file che stai modificando, salvarlo con vim e quindi tornare a ciò che era originariamente il file.

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)

Ovviamente non consiglio questo approccio in un sistema in cui sei preoccupato per la sicurezza, poiché per pochi secondi chiunque può leggere/modificare il file senza che tu te ne accorga.

utilizzo gksudo invece di sudo per GVim, ad es.

cmap w!! w !gksudo tee >/dev/null %
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top