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