J'essaie d'aller dans une session irb
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 saisi env.
pour le compléter, le message d'erreur suivant s'affiche:
$ 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 le résultat 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 résoudre le problème lorsque je ne suis pas un utilisateur root?
Vous avez trouvé un bogue dans la bibliothèque Bash Completion utilisée par Ubuntu.
Qu'est-ce que cela signifie?
Ubuntu utilise une bibliothèque d’achèvement de bash pour rendre l’achèvement de bash intelligent. Cette bibliothèque existe dans /usr/share/bash-completion/bash_completion
.
Essentiellement, cette bibliothèque déclare quelques fonctions intelligentes qui connaissent les commandes typiques et comment les compléter. Chaque fois que vous appuyez sur Tab, les fonctions de cette bibliothèque sont appelées et tentent de compléter votre ligne de commande actuelle. Ainsi, par exemple, si vous tapez apt-get i
Tab il complétera cela à apt-get install
. Si vous ne sourcez pas cette bibliothèque, vous ne disposez que de la complétude standard et primitive de bash - par exemple, si vous tapez apt-get i
Tab sans l'avoir recherchée, bash recherchera simplement des fichiers dans le répertoire en cours commençant par i
et tentera de compléter votre commande en fonction de ces noms de fichiers.
Pourquoi cela ne se produit-il pas en tant que root?
Parce que lorsque vous utilisez Sudo su
pour vous créer root
name__, la bibliothèque d'achèvement de bash n'est pas obtenue. Ce serait différent si vous utilisiez Sudo -i
pour vous créer root
name__. Je parie que vous voyez le virus alors, n'est-ce pas? Voir par exemple 'Sudo su -' vs 'Sudo -i' vs 'Sudo/bin/bash' - Quand est-il important d'utiliser ou pas du tout? si vous ne l'êtes pas familiariser avec les différences.
Dans mon cas, en tant qu'utilisateur normal, la bibliothèque est générée lorsque je lance un shell Bash car ~/.bashrc
source /etc/bash_completion
qui source /usr/share/bash-completion/bash_completion
.
Si j'utilise Sudo -i
pour me connecter en tant que root
name__, la bibliothèque est obtenue parce que /etc/profile
source /etc/profile.d/bash_completion.sh
qui source /usr/share/bash-completion/bash_completion
.
Pourquoi ce bogue 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
Vous semble familier? ;-) En effet, c’est exactement ce qui s’est passé dans les coulisses quand on a frappé Tab dans le contexte que vous avez décrit. Plus précisément, le bogue est dans la fonction _quote_readline_by_ref
déclarée par /usr/share/bash-completion/bash_completion
. Si vous avez recherché 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
exécute, entre autres choses, le eval
mentionné ci-dessus. Vous pouvez jeter un oeil si vous aimez. Et quand vous avez tapé env $(cat env.
Tab, en coulisse, cette fonction a été appelée avec exactement ces arguments. Donc c'est ce qui s'est passé.
Ce eval
hack était supposé résoudre un autre problème , mais je suppose qu'il a introduit cet autre bogue dans le processus.
Comment puis-je résoudre ce problème?
Il s'avère que ce bug a déjà été rapporté . Après avoir lu ce rapport de bogue, je vois trois façons de le résoudre:
corrige: 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 recommande de ne pas faire cela. La personne qui a écrit ce commentaire n'apparaît pas développeur de bash-complétion . Ce correctif entraînera simplement l'évaluation de l'opérande gauche de l'instruction sur false et empêchera ainsi que eval
se produise. Cependant, sans une bonne connaissance de ce que cette fonction est censée faire et dans quel contexte elle est appelée, il n’est pas clair si cela ne risque pas de casser certaines autres fonctionnalités voulues.
Obtenez la dernière version: Comme mentionné également dans ce rapport de bogue, ce bogue n'est pas présent dans git head (la modification de la fonction _quote_readline_by_ref
a été simplifiée, entre autres). 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 script bash_completion
dans /usr/share/bash-completion
(inutile de sauvegarder l'ancienne version à moins que cela ne vous rende plus sûr - si vous rencontrez des problèmes, Sudo apt-get install --reinstall bash-completion
devrait annuler les modifications que vous avez apportées sans problème.) comme je le recommande si vous êtes pressé de le réparer. :-)
Notez qu'aucune de ces solutions ne fera fonctionner l'achèvement de bash à l'intérieur d'une substitution de commande: comme mentionné dans ce même rapport de bogue, ceci est cassé dans Bash 4.3.