
Bei Verwendung der Tab-Vervollständigung in Bash $_
wird die Variable geändert:
$ mkdir test
$ cd <TAB><TAB> $_
bash: cd: -d: invalid option
cd: usage: cd [-L|[-P [-e]]] [dir]
(Dadurch <TAB><TAB>
werden alle Dateien im aktuellen Verzeichnis aufgelistet, aber ich verwende die Ausgabe letztendlich nicht und schreibe $_
stattdessen. Der in dieser Zeile ausgeführte Befehl lautet einfach cd $_
.)
Das erwartete Verhalten wäre eine Änderung in ./test
.
Wie kann ich verhindern, dass die Bash-Vervollständigung geändert wird $_
?
Antwort1
Sie verwenden diebash-completion
Paket (oder ein Derivat). Für jede Argumentvervollständigung des cd
Befehls (wie in der complete -p
Ausgabe gezeigt):
complete -o nospace -F _cd cd
Die _cd
Funktion wird aufgerufen, um die Vervollständigungen zu bestimmen (der Kürze halber leicht bearbeitet):
_cd()
{
local cur prev words cword
_init_completion || return
local IFS=$'\n' i j k
compopt -o filenames
if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
_filedir -d
return 0
fi
....
Wenn Sie beispielsweise ein Verzeichnis ohne CDPATH
Set abschließen, ist das zuletzt angezeigte Argument eines angezeigten Befehls -d
, und dieses wird automatisch in platziert _
. Es gibt mehrere andere Codepfade in dieser Funktion mit ähnlichen Nebeneffekten.
Da _
es sich um eine interne Bash handelt, ist ein herkömmliches Speichern/Wiederherstellen (wie beiIFS
) wird nicht wie erhofft funktionieren. Siekönntemach es mit einem kleinen Trick:
_cd()
{
local save_="$_"
...
: $save_
return 0
Sie müssen _
sofort beim Eintritt in eine Funktion speichern, :
ist der Nullbefehl, der an sich nichts tut, aber die üblichen Nebenwirkungen eines Befehls hat, wie z. B. das Setzen _
. Dieser Wiederherstellungsvorgang wird für jeden Rückgabepunkt jeder potenziell störenden Funktion erforderlich sein. Auch hier gibt es eine Feinheit: Normalerweise _
wird sofort nach einer Rückkehr von einer Funktion gesetzt (wie erwartet zum letzten Argument des Funktionsaufrufs), was diese Methode unwirksam machen würde. Dies geschieht jedoch nicht, wenn eine Vervollständigungsfunktion aufgerufen wird, da sie nicht explizit aufgerufen wird. Ich halte dies nicht für sehr robust ...
(Ich bevorzugeGeschichte Erweiterung, und bleiben Sie bei !$
dem, bei dem dieses Problem nicht auftritt.)