You're using the bash-completion package (or a derivative). For each argument completion of the cd command (as shown by the complete -p output):
complete -o nospace -F _cd cd
the _cd function is invoked to determine the completions (slightly edited for brevity):
_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
....
So for example, when you complete on a directory with no CDPATH set, the last-seen argument to a command seen is -d, and this is placed automatically in _. There are several other code paths in that function with similar side-effects.
Since _ is a bash internal, a conventional save/restore (as for IFS) won't work as hoped.
You could do it with a little trickery:
_cd()
{
local save_="$_"
...
: $save_
return 0
You must save _ immediately on entry to a function, : is the null command, which does nothing per-se but has the usual side-effects of a command, such as setting _. This restore operation will be required for each return point of each potentially disruptive function. There's a subtlety here too: normally _ is set immediately after a return from a function (to the last argument of the function call, as expected), which would make this method ineffective. But, this doesn't happen when a completion function is invoked, since it's not explicit invoked. I don't consider this to be very robust...
(I prefer history expansion, and stick to !$ which doesn't suffer this problem.)
readline) completion doesn't do this. Please indicate which version of bash, which completion package and/or the output ofcomplete -p.cd <TAB><TAB>should give you all possible completions (the 2nd tab),how are you entering$_?complete -pis here: js.f0i.de/complete-p.html