web-dev-qa-db-fra.com

Achèvement de l'onglet Bash: '-bash: inattendu EOF tout en recherchant le `)' -bash correspondant: erreur de syntaxe: fin inattendue du fichier

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?

18
eldosoa

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 iTab 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 iTab sans l'avoir recherchée, bash recherchera simplement des fichiers dans le répertoire en cours commençant par iet 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 rootname__, 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 rootname__. 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 rootname__, 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 evalmentionné 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 evalhack é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:

  1. 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 evalse 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.

  2. 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.

  1. 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 commande) et vous l'obtiendrez avec une version future d'Ubuntu. C'est ce que je vais faire ;-)
33
Malte Skoruppa