Comment le vim “écrire avec sudo” tour?
Beaucoup d'entre vous ont probablement vu la commande qui permet d'écrire sur un fichier qui a besoin de la racine de l'autorisation, même lorsque vous avez oublié d'ouvrir vim avec sudo:
:w !sudo tee %
Le truc c'est que je ne comprends pas ce qui est exactement ce qui se passe ici.
J'ai déjà pensé à ceci:
w
est pour cette
*:w_c* *:write_c*
:[range]w[rite] [++opt] !{cmd}
Execute {cmd} with [range] lines as standard input
(note the space in front of the '!'). {cmd} is
executed like with ":!{cmd}", any '!' is replaced with
the previous command |:!|.
de sorte qu'il passe toutes les lignes en entrée standard.
La !sudo tee
le cadre des appels tee
avec des privilèges d'administrateur.
Pour tous les sens, la %
devrait sortir le nom de fichier (comme un paramètre pour tee
), mais je ne peux pas trouver des références sur l'aide pour ce problème.
tl;dr quelqu'un Pourrait-il m'aider à disséquer cette commande?
- Serait
:w !sudo cat > %
ne pas fonctionner aussi bien, et de ne pas polluer la sortie standard? - non, cela ne fonctionne pas. Dans ce cas,
sudo
est appliqué àcat
, mais de ne pas>
, de sorte qu'il n'est pas permis. Vous pouvez essayer de l'exécution de l'ensemble de la commande dans un sudo shell interne est exécuté, comme:w !sudo sh -c "cat % > yams.txt"
, mais ça ne fonctionne pas non plus, parce que dans le shell interne est exécuté,%
est nul; vous aurez vide le contenu de votre fichier. - Vous pourriez probablement utiliser
:w !sudo sh -c 'cat $1 > yams.txt' - %
, mais je ne sais pas comment cela va gérer les caractères spéciaux ou des espaces - Je souhaite juste ajouter qu'après avoir tapé cette commande, un message d'avertissement peut apparaître. Si oui, appuyez sur L. Alors, il vous sera demandé d'appuyer sur entrée. Et vous, vous allez enfin avoir votre fichier enregistré.
- qui a déjà été suggéré et rejected:
sudo
s'applique àcat
de ne pas>
:w !sudo sh -c "cat >%"
en fait, il fonctionne tout aussi bien quesudo tee %
parce que Vim substitue le nom de fichier pour%
avant qu'il ne se fait jamais à la shell interne est exécuté. Cependant, aucun d'eux ne fonctionne que si le nom de fichier avec des espaces; que vous avez à faire:w !sudo sh -c "cat >'%'"
ou:w !sudo tee "%"
pour résoudre ce problème.- Enregistrer à l'aide de :W et recharger le fichier: commande W :executer:silent w !sudo tee % > /dev/null',|: modifier!
- Notez que cette astuce actuellement ne pas travail travailler avec
neovim
.
Vous devez vous connecter pour publier un commentaire.
Dans
:w !sudo tee %
...%
signifie "le fichier actuel"Comme eugène y souligné,
%
signifie "le nom du fichier en cours". Une autre utilisation de ce dans Vim est dans la substitution de commandes. Par exemple,:%s/foo/bar
signifie "dans le fichier actuel, remplacer les occurrences defoo
avecbar
." Si vous mettez du texte avant de taper:s
, vous verrez que les lignes en surbrillance prendre la place de%
que votre substitution de gamme.:w
n'est pas la mise à jour de votre fichierUne partie confuse de cette astuce est que vous pourriez penser
:w
est la modification de votre fichier, mais il ne l'est pas. Si vous avez ouvert et modifiéfile1.txt
, puis a couru:w file2.txt
, il serait un "enregistrer sous";file1.txt
ne serait pas modifié, mais le contenu de la mémoire tampon devra être envoyé àfile2.txt
.Au lieu de
file2.txt
, vous pouvez substituer un shell de commande pour recevoir le contenu de la mémoire tampon. Par exemple,:w !cat
va juste afficher le contenu.Si Vim n'était pas courir avec sudo accès, de son
:w
ne pouvez pas modifier un fichier protégé, mais si elle passe le contenu de la mémoire tampon à la coque, une commande dans le shell peut être exécuté avec sudo. Dans ce cas, nous utilisonstee
.Compréhension tee
Comme pour
tee
, l'image de latee
commande un T-en forme de pipe normale dans un bash de la tuyauterie de la situation: il dirige la sortie vers le fichier spécifié(s) et aussi envoie sur la sortie standard, qui peut être capturée par la prochaine canalisations de commande.Par exemple, dans
ps -ax | tee processes.txt | grep 'foo'
, la liste des processus sera écrit dans un fichier texte et transmisgrep
.(Diagramme créé avec Asciiflow.)
Voir le
té
de la page de manuel pour plus d'info.Té comme un hack
Dans la situation de votre question décrit, à l'aide de
tee
est un hack parce que nous sommes en ignorant la moitié de ce qu'il fait.sudo tee
écrit à notre fichier et envoie le contenu de la mémoire tampon de sortie standard, mais nous ignorons sortie standard. Nous n'avons pas besoin de passer quelque chose à l'autre, les canalisations de commande dans ce cas; nous sommes juste à l'aide detee
comme une alternative de l'écriture d'un fichier et que nous pouvons appeler avecsudo
.Faire cette astuce facile
Vous pouvez ajouter ceci à votre
.vimrc
pour rendre cette astuce facile à utiliser: il suffit de taper:w!!
.La
> /dev/null
partie explicitement jette la sortie standard, puisque, comme je l'ai dit, nous n'avons pas besoin de passer quelque chose à l'autre, les canalisations de commande.:sudow
?cmap
cartes d'une commande à une action.tee
pour sa capacité à écrire stdin vers un fichier. Je suis surpris de voir qu'il n'est pas un programme dont la fonction est de le faire (j'ai trouvé un programme, que je n'ai jamais entendu parler desponge
qui le fait). Je suppose que la caractéristique "écrire un flux de données vers un fichier" est effectuée par une coque intégrée. Ne Vim est!{cmd}
pas à la fourche d'un shell (un fork decmd
à la place)? Peut-être quelque chose qui est plus évidente serait d'utiliser une certaine variante desh -c ">"
plutôt quetee
.sponge
fait partie de lamoreutils
paquet sur à peu près tous de distribution à l'exception des distributions basées sur Debian.moreutils
a quelques assez agréable outils qui sont sur pied d'égalité avec plus d'outils communs commexargs
ettee
.cat
s'exécute en tant que root, et la sortie est redirigée par le shell, ce qui n'est pas exécuté en tant que root. C'est le même queecho hi > /read/only/file
.:%s/foo/bar
signifie " dans le fichier courant, ...'" - Hein. J'ai toujours lu que visuellement, comme dans, "0 à partir du haut à 0 à partir du bas":w
. Vous pouvez envisager d'ajouter un utilisateur défini commande à votre.vimrc
command! Wsudo w !sudo tee > /dev/null %
. Cela peut être invoquée comme:Wsudo
tee
explication de la commande a été quelque chose de ce monde. Pur Brillant!w!!
raccourci est très joli, mais il présente un décalage perceptible lors de la frappe:w
comme indiqué par @JackRowlingson. Au lieu d'ajouter un:Wsudo
de commande, il semble que le remplacement decmap
avecca
résoudre le problème, mais je ne comprends pas tout cela. Je copie-collé aveuglément à partir de cette Github question.Dans la ligne de commande,
%
représente le nom du fichier en cours. Ceci est documenté dans:aider cmdline-spécial
:Comme vous l'avez déjà trouvé,
:w !cmd
tuyaux le contenu de la mémoire tampon active à une autre commande. Ceté
n'est la copie de la norme d'entrée à un ou plusieurs fichiers, et également sur la sortie standard. Par conséquent,:w !sudo tee % > /dev/null
efficacement écrit le contenu du buffer dans le fichier en cours tout en étant root. Une autre commande qui peut être utilisé pour cela estdd
:Comme un raccourci, vous pouvez ajouter cette cartographie à votre
.vimrc
:Ci-dessus, vous pouvez taper
:w!!<Enter>
pour enregistrer le fichier en tant que root.:help _%
met en place ce que vous avez entré, mais:help %
apporte l'attache-clé correspondante. Je n'aurais pas pensé à essayer le trait de soulignement préfixe, est-ce un motif quelconque dans la documentation de vim? Existe-il d'autres "spécial" de choses à faire quand vous cherchez de l'aide?help
de commande pour passer à une balise. Vous pouvez voir les balises disponibles avec:h help-tags
. Vous pouvez également utiliser la ligne de commande de l'achèvement de voir matching tags::h cmdline<Ctrl-D>
(ou:h cmdline<Tab>
si vous définissezwildmode
en conséquence)cmap w!! w !sudo tee % > /dev/null
dans mon .fichiers vimrc pour faire ce travail. Est le%
égaré dans la réponse ci-dessus? (Pas de vim expert ici.)sudo tee > /dev/null /path/to/current/file
qui n'a pas vraiment de sens. (Allant à la modifier)tee
pipe entre les deux, pour. Toujours étrange qu'elle n'a pas de travail pour @DMfll.Cela fonctionne aussi bien:
Cela est inspiré par le commentaire de @Nathan Long.
AVIS:
"
doit être utilisé à la place de'
parce que nous voulons%
être développé avant de passer à la coque.tee
avec/usr/bin/tee
pour éviter le CHEMIN d'accès de modification des attaques.:w
- Écrire un fichier.!sudo
Appel shell commande sudo.tee
- La sortie de l'écriture (vim :w) commande redirigé à l'aide de té. Le % est rien, mais le nom du fichier en cours c'est à dire /etc/apache2/conf.d/mediawiki.conf. En d'autres termes té de la commande est exécutée en tant que root et il prend de l'entrée standard et l'écrire dans un fichier représenté par %. Cependant, cette vous invite à recharger le fichier de nouveau (touche L pour charger des changements dans vim):tutoriel lien
La accepté de répondre couvre tout, alors je vais juste donner un autre exemple de raccourci que j'utilise, pour l'enregistrement.
L'ajouter à votre
etc/vim/vimrc
(ou~/.vimrc
):cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' <bar> edit!
Où:
cnoremap
: raconte vim que le raccourci suivantes est d'être associé à la ligne de commande.w!!
: le raccourci lui-même.execute '...'
: commande exécuter la chaîne suivante.silent!
: exécuter en mode silencieuxwrite !sudo tee % >/dev/null
: l'OP question, a ajouté une redirection de messages àNULL
de faire une commande clean<bar> edit!
: cette astuce est la cerise du gâteau: il fait aussi appel à laedit
de commande pour recharger la mémoire tampon, puis d'éviter des messages tels que la mémoire tampon a changé.<bar>
est la façon d'écrire le pipe symbole de séparer les deux commandes ici.Espère que cela aide. Voir aussi pour d'autres problèmes:
Je voudrais suggérer une autre approche de la "Oups j'ai oublié d'écrire
sudo
lors de l'ouverture de mon fichier" question:Au lieu de recevoir un
permission denied
, et d'avoir à les saisir:w!!
, je le trouve plus élégant d'avoir un conditionnelvim
commande qui nesudo vim
si le propriétaire du fichier estroot
.C'est aussi facile à mettre en œuvre (il y a peut-être même plus élégant implémentations, je suis clairement pas un bash-guru):
Et il fonctionne vraiment bien.
C'est un plus
bash
approche centrée sur qu'unvim
-on donc pas tout le monde peut l'aime.De cours:
root
mais nécessitesudo
, mais la fonction peut être modifiée en tout cas)vim
pour la lecture seule d'un fichier (pour autant que je suis concerné, je l'utilisetail
oucat
pour les petits fichiers)Mais je trouve que cela apporte une bien meilleure dev expérience utilisateur, qui est quelque chose qui à mon humble avis, tend à être oublié lors de l'utilisation de
bash
. 🙂root
le mot de passe est demandé.