запретить автодополнение bash изменять переменную подчеркивания $_

запретить автодополнение bash изменять переменную подчеркивания $_

При использовании автодополнения клавишей 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, которая сама по себе ничего не делает, но имеет обычные побочные эффекты команды, такие как установка _. Эта операция восстановления потребуется для каждой точки возврата каждой потенциально разрушительной функции. Здесь также есть тонкость: обычно _устанавливается сразу после возврата из функции (к последнему аргументу вызова функции, как и ожидалось), что сделало бы этот метод неэффективным. Но этого не происходит, когда вызывается функция завершения, поскольку она не вызывается явно. Я не считаю это очень надежным...

(Я предпочитаюистория расширение, и придерживайтесь !$того, который не страдает от этой проблемы.)

Связанный контент