Vous avez trouvé un bogue dans la bibliothèque de complétion de Bash utilisée par Ubuntu.
Qu'est-ce que ça veut dire?
Ubuntu utilise une bibliothèque de complétion bash pour rendre la complétion bash intelligente. Cette bibliothèque vit /usr/share/bash-completion/bash_completion
.
Essentiellement, cette bibliothèque déclare quelques fonctions intelligentes qui connaissent les commandes typiques et comment les exécuter. Chaque fois que vous appuyez sur Tab, les fonctions de cette bibliothèque sont appelées et tentent de terminer votre ligne de commande actuelle. Ainsi, par exemple, si vous tapez, apt-get i
Tabcela se terminera apt-get install
. Si vous ne sourcez pas cette bibliothèque, vous n'avez que la complétion bash primitive standard - donc par exemple si vous tapez apt-get i
Tabsans l'avoir obtenue, bash recherchera simplement les fichiers dans le répertoire courant en commençant par i
et tentera de terminer votre commande selon ces noms de fichiers.
Pourquoi cela ne se produit-il pas en tant que root?
Parce que lorsque vous utilisez sudo su
pour vous fabriquer root
, la bibliothèque de complétion bash n'est pas sourcée. Ce serait différent si vous vous sudo -i
faisiez vous-même root
. Je parie que vous voyez le bug alors, n'est-ce pas? Voir par exemple 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - quand est-ce important ou qui est-il important? si vous n'êtes pas familier avec les différences.
Dans mon cas, en tant qu'utilisateur normal, la bibliothèque est sourcée lorsque je démarre un shell Bash parce que les ~/.bashrc
sources sont les /etc/bash_completion
sources /usr/share/bash-completion/bash_completion
.
Si j'utilise sudo -i
pour me connecter en tant que root
, la bibliothèque est sourcée parce que les /etc/profile
sources /etc/profile.d/bash_completion.sh
quelles sources /usr/share/bash-completion/bash_completion
.
Pourquoi ce bug se produit-il?
Essayez d'exécuter cette commande:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Ça vous semble familier? ;-) En effet, c'est exactement ce qui s'est passé dans les coulisses lorsque vous avez frappé Tabdans le contexte que vous avez décrit. Plus précisément, le bug se trouve dans la fonction _quote_readline_by_ref
déclarée par /usr/share/bash-completion/bash_completion
. Si vous avez trouvé ce fichier, vous devriez avoir cette fonction disponible. Alors, essayez ceci:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Compte tenu de ces arguments, la fonction _quote_readline_by_ref
effectue, entre autres, celle eval
mentionnée ci-dessus. Vous pouvez jeter un œil si vous le souhaitez. Et lorsque vous avez tapé env $(cat env.
Tab, dans les coulisses, cette fonction a été appelée avec exactement ces arguments. Voilà donc ce qui s'est passé.
Ce eval
hack était censé résoudre un autre problème , mais je suppose qu'il a introduit cet autre bug dans le processus.
Comment je le répare?
Il s'avère que ce bogue a déjà été signalé . Après avoir lu ce rapport de bogue, je vois trois façons de le corriger:
Corrigez-le: dans l'un des commentaires de ce rapport de bogue, quelqu'un suggère de remplacer la ligne
[[ ${!2} == \$* ]] && eval $2=${!2}
dans la fonction _quote_readline_by_ref
dans le fichier /usr/share/bash-completion/bash_completion
par la ligne
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Je déconseille de faire cela. La personne qui a écrit ce commentaire ne semble pas être un développeur de bash-complètement . Ce correctif entraînera simplement l'opérande gauche de l'instruction à évaluer à faux et empêchera ainsi que cela se eval
produise. Cependant, sans une bonne connaissance de ce que cette fonction est censée faire et dans quels contextes elle est appelée, il est difficile de savoir si cela ne risque pas de casser certaines autres fonctionnalités prévues.
Obtenez la dernière version: Comme également mentionné dans ce rapport de bogue, ce bogue n'est pas présent dans git head (dans lequel, entre autres changements, la fonction _quote_readline_by_ref
a été simplifiée). Vous pouvez simplement cloner la révision actuelle depuis Git:
git clone https://salsa.debian.org/debian/bash-completion.git
... puis copiez la dernière version du bash_completion
script dans /usr/share/bash-completion
(pas de besoin urgent de sauvegarder l'ancienne version à moins que cela ne vous rende plus en sécurité - si vous rencontrez des problèmes, sudo apt-get install --reinstall bash-completion
vous devez annuler toutes les modifications que vous avez apportées.) C'est ainsi que je recommander si vous êtes pressé de résoudre ce problème. :-)
Notez qu'aucune de ces solutions ne fera fonctionner bash à l'intérieur de la substitution de commandes: comme mentionné dans ce même rapport de bogue, cela est cassé dans Bash 4.3.
- Asseyez-vous et attendez: Tôt ou tard, une nouvelle version sera publiée (ce qui peut même corriger l'achèvement de bash dans la substitution de commandes) et vous l'obtiendrez avec une future version d'Ubuntu. C'est ce que je veux faire ;-)