J'essaie d'entrer dans une irb
session avec des variables d'environnement spécifiques à partir d'un fichier avec cette commande:
$ env $(cat env.sh) irb
Mais lorsque j'essaie d'appuyer sur Tab
après avoir tapé env.
pour le terminer, j'obtiens l'erreur suivante:
$ env $(cat env.-bash: unexpected EOF while looking for matching `)'
-bash: syntax error: unexpected end of file
Une autre chose intéressante est que si je suis connecté en tant que root, cette erreur ne se produit pas.
Voici la sortie de find ~ -uid 0
:
$ find ~ -uid 0
/home/(redacted)/.rpmdb
/home/(redacted)/.rpmdb/Group
/home/(redacted)/.rpmdb/Conflictname
/home/(redacted)/.rpmdb/Installtid
/home/(redacted)/.rpmdb/Sha1header
/home/(redacted)/.rpmdb/Providename
/home/(redacted)/.rpmdb/__db.002
/home/(redacted)/.rpmdb/Requirename
/home/(redacted)/.rpmdb/Sigmd5
/home/(redacted)/.rpmdb/__db.001
/home/(redacted)/.rpmdb/Obsoletename
/home/(redacted)/.rpmdb/.dbenv.lock
/home/(redacted)/.rpmdb/Name
/home/(redacted)/.rpmdb/Basenames
/home/(redacted)/.rpmdb/Triggername
/home/(redacted)/.rpmdb/Packages
/home/(redacted)/.rpmdb/Dirnames
/home/(redacted)/.rpmdb/__db.003
Quelqu'un peut-il m'expliquer pourquoi cela se produit et si oui, comment puis-je le corriger lorsque je ne suis pas un utilisateur root?
command-line
bash
auto-completion
eldosoa
la source
la source
sudo su
.find ~ -uid 0
.~
est/home/something
.Réponses:
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 termineraapt-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 tapezapt-get i
Tabsans l'avoir obtenue, bash recherchera simplement les fichiers dans le répertoire courant en commençant pari
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 fabriquerroot
, la bibliothèque de complétion bash n'est pas sourcée. Ce serait différent si vous voussudo -i
faisiez vous-mêmeroot
. 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 queroot
, 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:
Ç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:Compte tenu de ces arguments, la fonction
_quote_readline_by_ref
effectue, entre autres, celleeval
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
dans la fonction
_quote_readline_by_ref
dans le fichier/usr/share/bash-completion/bash_completion
par la ligneJe 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:... 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.
la source
sudo su
pour devenir root, il ne source pas la bibliothèque, mais il sera sourcé lorsque vous l'utiliserez à lasudo -i
place, ce qui est le moyen prévu pour obtenir une session root interactive. Quant à votre question: étant donné que tout shell bash lit~/.bashrc
qui finit par sources la bibliothèque, et qu'il n'y a aucun moyen de "dé-source" un fichier, je ne vois pas de manière complètement simple. Voici un piratage possible: subordonnez le sourcing de la bibliothèque à une variable d'environnement, par exempleNOCOMPL
, non définie dans votre~/.bashrc
, ...