
При использовании автодополнения клавишей Tab в bash $_
переменная изменяется:
$ mkdir test
$ cd <TAB><TAB> $_
bash: cd: -d: invalid option
cd: usage: cd [-L|[-P [-e]]] [dir]
(Команда <TAB><TAB>
выведет список всех файлов в текущем каталоге, но я не использую вывод, а $_
просто записываю. Команда, выполняемая в этой строке, будет просто cd $_
.)
Ожидаемым поведением будет изменение на ./test
.
Как предотвратить изменение автодополнения bash $_
?
решение1
Вы используетеbash-completion
Пакет (или производный). Для каждого аргумента завершение команды cd
(как показано в complete -p
выводе):
complete -o nospace -F _cd cd
функция _cd
вызывается для определения завершений (слегка отредактировано для краткости):
_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
....
Так, например, когда вы завершаете работу над каталогом, в котором нет CDPATH
набора, последний увиденный аргумент команды seen — -d
, и он автоматически помещается в _
. В этой функции есть несколько других путей кода с похожими побочными эффектами.
Так как _
это внутренний bash, обычное сохранение/восстановление (как дляIFS
) не будет работать так, как хотелось бы. Вымогсделайте это с помощью небольшой хитрости:
_cd()
{
local save_="$_"
...
: $save_
return 0
Вы должны сохранить _
немедленно при входе в функцию, :
это команда null, которая сама по себе ничего не делает, но имеет обычные побочные эффекты команды, такие как установка _
. Эта операция восстановления потребуется для каждой точки возврата каждой потенциально разрушительной функции. Здесь также есть тонкость: обычно _
устанавливается сразу после возврата из функции (к последнему аргументу вызова функции, как и ожидалось), что сделало бы этот метод неэффективным. Но этого не происходит, когда вызывается функция завершения, поскольку она не вызывается явно. Я не считаю это очень надежным...
(Я предпочитаюистория расширение, и придерживайтесь !$
того, который не страдает от этой проблемы.)