
Ao usar o preenchimento 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]
(Ele <TAB><TAB>
listará todos os arquivos no diretório atual, mas não acabo usando a saída e escrevo $_
. O comando executado nesta linha será apenas cd $_
.)
O comportamento esperado seria mudar para ./test
.
Como posso evitar que a conclusão do bash seja alterada $_
?
Responder1
Você está usando obash-completion
pacote (ou um derivado). Para cada conclusão de argumento do cd
comando (conforme mostrado na complete -p
saída):
complete -o nospace -F _cd cd
a _cd
função é invocada para determinar as conclusões (ligeiramente editada por questões de 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ê completa um diretório sem CDPATH
conjunto, o último argumento visto para um comando visto é -d
e é colocado automaticamente em _
. Existem vários outros caminhos de código nessa função com efeitos colaterais semelhantes.
Como _
é um bash interno, um salvamento/restauração convencional (como paraIFS
) não funcionará como esperado. Vocêpoderiafaça isso com um pouco de truque:
_cd()
{
local save_="$_"
...
: $save_
return 0
Você deve salvar _
imediatamente ao entrar em uma função, :
é o comando nulo, que não faz nada por si só, mas tem os efeitos colaterais usuais de um comando, como setting _
. Esta operação de restauração será necessária para cada ponto de retorno de cada função potencialmente perturbadora. Há uma sutileza aqui também: normalmente _
é definido imediatamente após o retorno de uma função (até o último argumento da chamada da função, como esperado), o que tornaria esse método ineficaz. Porém, isso não acontece quando uma função de conclusão é invocada, uma vez que não é invocada explícitamente. Não considero isso muito robusto...
(Eu prefiroexpansão da história, e atenha-se ao !$
que não sofre esse problema.)