impede que o preenchimento do bash altere a variável de sublinhado $ _

1

Ao usar a conclusão de tabulação no bash, a variável $_ é alterada:

$ mkdir test
$ cd <TAB><TAB> $_
bash: cd: -d: invalid option
cd: usage: cd [-L|[-P [-e]]] [dir]

(O <TAB><TAB> listará todos os arquivos no diretório atual, mas eu não acabarei usando a saída e escreva $_ . O comando executado nesta linha será apenas cd $_ .)

O comportamento esperado seria mudar para ./test .

Como posso evitar que o preenchimento do bash altere $_ ?

    
por f0i 12.10.2013 / 10:47

1 resposta

2

Você está usando o pacote bash-completion (ou um derivativo). Para cada conclusão do argumento do comando cd (conforme mostrado pelo complete -p output):

complete -o nospace -F _cd cd

A função _cd é invocada para determinar as conclusões (ligeiramente editadas para brevidade):

_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
    ....

Por exemplo, quando você conclui em um diretório sem CDPATH set, o último argumento visto para um comando visto é -d , e isso é colocado automaticamente em _ . Existem vários outros caminhos de código nessa função com efeitos colaterais similares.

Como _ é um bash interno, um save / restore convencional (como para IFS ) não funcionará como esperado. Você poderia fazer isso com um pequeno truque:

_cd()
{
    local save_="$_"
    ...
    : $save_
    return 0

Você deve salvar _ imediatamente na entrada de uma função, : é o comando nulo, que não faz nada por si, mas tem os efeitos colaterais usuais de um comando, como definir _ . Essa operação de restauração será necessária para cada ponto de retorno de cada função potencialmente prejudicial. Há uma sutileza aqui também: normalmente _ é definido imediatamente após um retorno de uma função (para o último argumento da chamada de função, como esperado), o que tornaria este método ineficaz. Mas isso não acontece quando uma função de conclusão é invocada, uma vez que não é invocada explicitamente. Eu não considero isso muito robusto ...

(Eu prefiro expansão do histórico , e fico com !$ que não sofre este problema.)

    
por 13.10.2013 / 22:41