Pourquoi nullglob affecte l'achèvement de l'onglet?

Après shopt -s nullglob , j'ai remarqué que l'achèvement de l'onglet a complètement cessé de fonctionner. Pourquoi serait-ce? extglob est apparemment bénin , quoi d'autre pourrait affecter nullglob?

Observé le:

  • Ubuntu 14.04 (bash 4.3.11(1)-release )
  • Arch Linux (bash 4.3.42(1)-release )

Contrairement à extglob , nullglob fait une énorme différence dans le comportement de la coquille. Cela signifie qu'un mot contenant des caractères generics susceptibles de ne correspondre à rien entraîne la disparition d'un mot au lieu d'être conservé.

Dans la plupart des cas, le code qui casse avec nullglob se cassera sans lui, si un certain directory contient des files qui correspondent au model non guidé. Selon le model, l'existence de tels files peut être plus ou less probable (et cela peut être impossible si les scripts contrôlent les noms de files présents, par exemple parce qu'il passe à un directory temporaire qu'il remplit).

La complétion des tabs de Bash n'est pas affectée par nullglob par défaut, mais elle est affectée si vous activez l'achèvement programmable, car une partie du code bash qui implémente l'achèvement programmable n'est pas robuste.

En regardant ce qui se passe en complétant l'argument de ls avec set -x activé, je vois que la sortie avec et sans nullglob commence à différer à

 + [[ 0 -gt 0 ]] + ref='words[0]' + eval 'words[0]=${!ref}${COMP_WORDS[i]}' ++ words[0]=ls + line=' ' 

(travail) vs.

 + [[ 0 -gt 0 ]] + ref='words[0]' + eval + line=' ' 

avec nullglob. Voir cette ligne d' eval ? C'est un signe que l'argument ressemblait à un model glob. Le code correspondant se trouve dans la fonction __reassemble_comp_words_by_ref :

  # Append word separator to current or new word ref="$2[$j]" eval $2[$j]=\${!ref}\${COMP_WORDS[i]} 

[ $2[$j]=\${!ref}\${COMP_WORDS[i]} est un model générique, et avec nullglob , il est éliminé car il ne correspond à rien. Cela serait également possible même sans nullglob si le directory actuel contenait un file appelé words0=${!ref}${COMP_WORDSi} – c'est assez exotique, mais cela pourrait arriver.

Le correctif consiste à append les guillemets manquants:

  eval "$2[$j]=\${!ref}\${COMP_WORDS[i]}" 

Il y a probablement d'autres parties de ce script qui ont besoin de corrections similaires, je n'ai pas étudié plus loin.

Ceci est un bug dans bash_completion (pas dans bash lui-même). Il a été signalé en 2012 et la fixation est sur la feuille de route pour la version 3.0.