253 votes

Obtenir les autorisations root sur un fichier à l'intérieur de vi?

Souvent, lors de l'édition des fichiers de configuration, j'en ouvre un avec vi et quand je vais le sauver, je réalise que je n'ai pas tapé

 sudo vi filename
 

Est-il possible de donner des privilèges vi sudo pour enregistrer le fichier? Je me souviens d'avoir vu quelque chose à ce sujet en regardant des choses à propos de vi tout à l'heure, mais maintenant je ne peux pas le trouver.

310voto

hop Points 15423

% est remplacé par le nom du fichier en cours, vous pouvez donc utiliser:

:w !sudo tee %

(vim va détecter que le fichier a été modifié et vous demande si vous voulez qu'il soit rechargé.)

Comme un raccourci, vous pouvez définir votre propre commande. Placez le code suivant dans votre .vimrc:

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

Ci-dessus, vous pouvez taper :W<Enter> pour enregistrer le fichier. Depuis que j'ai écrit cela, je l'ai trouvé plus agréable (à mon avis) pour ce faire:

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

De cette façon, vous pouvez taper :w!! et il sera étendu à la totalité de la ligne de commande, en laissant le curseur à la fin, de sorte que vous pouvez remplacer l' % avec un nom de fichier de votre propre, si vous le souhaitez.

36voto

Mark Harrison Points 77152

En général, vous ne pouvez pas modifier l'identifiant utilisateur effectif du processus vi, mais vous pouvez le faire:

  :w !sudo tee myfile 

20voto

Zenexer Points 4192

Commune De Mises En Garde

La méthode la plus courante de se déplacer dans le fichier en lecture seule problème est d'ouvrir un tuyau dans le fichier en cours en tant que super-utilisateur à l'aide d'une mise en œuvre de l' sudo tee. Cependant, tous de la plus populaire des solutions que j'ai trouvé autour de l'Internet ont une combinaison de plusieurs mises en garde:

  • L'intégralité du fichier est écrit sur le terminal, ainsi que le fichier. Cela peut être long pour les gros fichiers, en particulier via des connexions réseau lentes.
  • Le fichier perd ses modes et des attributs similaires.
  • Les chemins de fichiers avec des caractères spéciaux ou des espaces pourraient ne pas être traités correctement.

Solutions

Pour contourner tous ces problèmes, vous pouvez utiliser la commande suivante:

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

Ceux-ci peuvent être raccourcie, respectueusement:

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

Explication

: commence la commande; vous aurez besoin de ce type de personnage dans le mode normal pour commencer la saisie d'une commande. Il doit être omis dans les scripts.

sil[ent] supprime la sortie de la commande. Dans ce cas, nous voulons arrêter l' Press any key to continue-comme d'invite de commandes qui s'affiche après l'exécution de l' :! commande.

exec[ute] exécute une chaîne de commande. On ne peut pas exécuter :write car il n'est pas nécessaire d'appel de fonction.

! représente l' :! commande: la seule commande que :write accepte. Normalement, :write accepte un chemin d'accès au fichier dans lequel écrire. :! sur son propre exécute une commande dans un shell (par exemple, à l'aide de bash -c). Avec :write, il doit exécuter la commande dans le shell, puis d'écrire la totalité du fichier à stdin.

sudo devrait être évident, c'est pourquoi vous êtes ici. Exécuter une commande en tant que super-utilisateur. Il y a beaucoup d'informations à travers le net à propos de comment cela fonctionne.

tee tuyaux stdin le fichier donné. :write écrira stdin, alors que le super-utilisateur tee recevrez le contenu du fichier et écrire le fichier. Il ne va pas créer un nouveau fichier--remplacer simplement le contenu--modes de fichier et les attributs seront préservés.

shellescape() s'échappe les caractères spéciaux dans le chemin d'accès au fichier approprié pour le shell courant. Avec un seul paramètre, il faut généralement juste placer le chemin d'accès entre guillemets, comme nécessaire. Puisque nous sommes l'envoi d'une coque intégrale en ligne de commande, nous allons vous souhaitez passer une valeur non nulle en tant que deuxième argument pour activer la barre oblique inverse-fuyant d'autres caractères spéciaux qui pourraient autrement le voyage jusqu'à la coquille.

@% lit le contenu de l' % registre, qui contient le tampon courant du nom de fichier. Ce n'est pas nécessairement un chemin d'accès absolu, afin de s'assurer que vous n'avez pas changé le répertoire courant. Dans certaines solutions, vous verrez commerciale au symbole omis. Selon l'emplacement, % est une expression valide et a le même effet que la lecture de l' % s'inscrire. Imbriquée à l'intérieur d'une autre expression, le raccourci est généralement rejetée, cependant: comme dans ce cas.

>NUL et >/dev/null redirection stdout à la plate-forme du périphérique null. Même si nous avons réduit au silence la commande, nous ne voulons pas que tous les frais généraux associés à la tuyauterie stdin retour à vim--mieux pour vider le plus tôt possible. NUL est le nul de l'appareil sur le DOS, MS-DOS et Windows, pas un fichier valide. Comme de Windows 8 redirections NUL n'étaient pas le résultat dans un fichier nommé NUL en cours d'écriture. Essayez de créer un fichier sur votre bureau nommé NUL, avec ou sans extension de fichier: il vous sera impossible de le faire. (Il y a plusieurs autres noms de périphériques de Windows, qui peut être bon de connaître.)

~/.vimrc

Dépend De La Plateforme

Bien sûr, vous ne voulez pas de mémoriser ces et de les taper à chaque fois. Il est beaucoup plus facile à établir la commande appropriée à une simplification de la commande de l'utilisateur. Pour ce faire, sur POSIX, vous pouvez ajouter la ligne suivante à votre ~/.vimrc le fichier, de le créer si il n'existe pas déjà:

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

Cela vous permettra de type :W (sensible à la casse) de commande d'écrire le fichier en cours avec des super-utilisateur autorisations, beaucoup plus facile.

Indépendant De La Plateforme

J'utilise une plate-forme indépendante ~/.vimrc le fichier qui se synchronise sur les ordinateurs, j'ai donc ajouté plate-forme multi-fonctionnalité de la mine. Voici un ~/.vimrc avec seulement les paramètres pertinents:

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

11voto

ephemient Points 87003

Si vous utilisez Vim , il y a un script disponible nommé sudo.vim . Si vous trouvez que vous avez ouvert un fichier dont vous avez besoin d'un accès root à lire, tapez

 : e sudo:% 

Vim remplace le% par le nom du fichier courant, et sudo: demande au script sudo.vim de prendre le relais pour la lecture et l'écriture.

7voto

Chris Jester-Young Points 102876

Le conseil de Ryan est généralement bon, cependant, si vous suivez l'étape 3, ne déplacez pas le fichier temporaire; il aura la mauvaise propriété et les autorisations. Au lieu de cela, sudoedit le fichier correct et lire dans le contenu (en utilisant :r ou similaire) du fichier temporaire.

Si vous suivez l'étape 2, utilisez :w! pour forcer l'écriture du fichier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X