Warum wirkt sich nullglob auf die Tab-Vervollständigung aus?

7

Danach shopt -s nullglobbemerkte ich, dass die Tab-Vervollständigung nicht mehr funktionierte. Warum sollte das so sein? extglobist anscheinend gutartig , was könnte nullglob sonst noch beeinflussen?

Beobachtet am:

  • Ubuntu 14.04 (Bash 4.3.11(1)-release)
  • Arch Linux (Bash 4.3.42(1)-release)
muru
quelle

Antworten:

8

Im Gegensatz zu extglob, nullglobmacht einen großen Unterschied in dem Shell - Verhalten. Dies bedeutet, dass ein Wort mit Platzhalterzeichen, die wahrscheinlich mit nichts übereinstimmen, dazu führt, dass ein Wort verschwindet, anstatt beibehalten zu werden.

In den meisten Fällen würde Code, der mit bricht nullglob, auch ohne brechen, wenn ein bestimmtes Verzeichnis Dateien enthält, die zufällig mit dem nicht zitierten Muster übereinstimmen. Abhängig vom Muster kann das Vorhandensein solcher Dateien mehr oder weniger wahrscheinlich sein (und es kann unmöglich sein, wenn das Skript steuert, welche Dateinamen vorhanden sind, z. B. weil es in ein temporäres Verzeichnis wechselt, das es auffüllt).

Die Tab-Vervollständigung von Bash wird standardmäßig nicht von nullglob beeinflusst. Sie wird jedoch beeinflusst, wenn Sie die programmierbare Vervollständigung aktivieren, da ein Teil des Bash-Codes, der die programmierbare Vervollständigung implementiert, nicht robust ist.

Wenn ich mir anschaue, was passiert, wenn das Argument von lsmit set -xaktiviert abgeschlossen wird, sehe ich, dass die Ausgabe mit und ohne nullglobStart bei unterschiedlich ist

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

(arbeiten) vs.

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

mit nullglob. Sehen Sie diese evalLinie? Das ist ein Zeichen dafür, dass das Argument wie ein Glob-Muster aussah. Der entsprechende Code befindet sich in der __reassemble_comp_words_by_refFunktion:

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

[ist ein Platzhalter, also $2[$j]=\${!ref}\${COMP_WORDS[i]}ein Platzhaltermuster, und mit nullglobwird es eliminiert, da es mit nichts übereinstimmt. Dies würde auch ohne Gewinn ausfallen, nullglobwenn das aktuelle Verzeichnis eine Datei mit dem Namen enthält words0=${!ref}${COMP_WORDSi}- das ist ziemlich exotisch, aber es könnte passieren.

Die Lösung besteht darin, die fehlenden doppelten Anführungszeichen hinzuzufügen:

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

Es gibt wahrscheinlich andere Teile dieses Skripts, die ähnliche Korrekturen benötigen, die ich nicht weiter untersucht habe.

Dies ist ein Fehler in bash_completion (nicht in bash selbst). Es wurde 2012 gemeldet und steht auf der Roadmap für Version 3.0.

Gilles 'SO - hör auf böse zu sein'
quelle
Danke, Gilles! shopt -s nullglobMeinen Sie damit, dass das Deaktivieren der automatischen Vervollständigung von Dateinamen nach Registerkarte ein Fehler in bash_completion ist und in bash 3.0 behoben wurde? Ich habe immer noch das Problem in Bash 4.3
Tim
@ Tim Es ist in bash_completion, nicht in bash. Die Version von Bash ist nicht relevant. Sie benötigen (warten) bash_completion 3.0.
Gilles 'SO - hör auf böse zu sein'