Um traçado simples
Primeiro, você pode descobrir o que realmente acontece quando você usa o bash completion com o comando cd
:
$ complete -p | grep cd
complete -F _filedir_xspec cdiff
complete -o nospace -F _cdrecord wodim
complete -o nospace -F _cdrecord cdrecord
complete -o nospace -F _cd cd
Você pode ver uma função _cd
será chamada quando você usar a conclusão com cd
. Então você sabe que alguma coisa aconteceu dentro da função _cd
, o valor da variável $_
foi alterado.
Olhando para a função _cd
: (No meu Ubuntu 12.04.4, está em /etc/bash_completion
)
# This meta-cd function observes the CDPATH variable, so that cd additionally
# completes on directories under those specified in CDPATH.
#
_cd()
{
local cur IFS=$'\n' i j k
_get_comp_words_by_ref cur
# try to allow variable completion
if [[ "$cur" == ?(\)\$* ]]; then
COMPREPLY=( $( compgen -v -P '$' -- "${cur#?(\)$}" ) )
return 0
fi
....
_filedir -d
if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
i=${COMPREPLY[0]}
if [[ "$i" == "$cur" && $i != "*/" ]]; then
COMPREPLY[0]="${i}/"
fi
fi
return 0
}
Ele faz muitas coisas, faz com que seu antigo $_
seja perdido. Talvez você tenha problemas com a linha _filedir -d
. (No meu teste, eu tenho $_
alterado para -d
)
Para evitar que o seu $_
desejado seja perdido, você pode salvar seu valor imediatamente quando inserir a função _cd
e restaurar esse valor para $_
antes de deixar o _cd
:
_cd()
{
local __=$_
....
: $__
return 0
}
O truque aqui é :
, isso significa não fazer nada em bash
e tem um parâmetro $__
(que é seu valor $_
desejado), fazendo com que $_
seja definido como valor antigo antes de você insira a função _cd
.
Conclusão
É muito difícil fazer com que bash completion
não desperdice a variável $_
. Com o exemplo acima, você só impediu que ele fosse descartado com cd
. Com outras funções em bash_completion
e todos os arquivos em /etc/bash_completion.d/
, você precisa fazer a mesma coisa. Esta não é uma solução robusta.
Se você deseja obter o último parâmetro da última linha de comando, tente usar bash history expansion
:
$ echo 1 2 3
1 2 3
$ echo !$
echo 3
3