I have years of experience on Slackware linux, and have never seen this problem there. Lately I have been administering Debian servers, and this has become an annoyance.

I frequently use "$_" in a bash command to repeat the final argument of the previously-typed command. Sometimes, I get the following behavior:

dschrag@mo:~/dev/dancer$ ls -l app/db/schema/
total 12
-rw-r--r-- 1 dschrag dschrag 268 May 19 10:51 gau_account.sql
-rw-r--r-- 1 dschrag dschrag 558 May 19 13:02 gau_import.sql
-rw-r--r-- 1 dschrag dschrag 270 May 19 13:09 gau_source.sql
dschrag@mo:~/dev/dancer$ cd $_
-bash: cd: _filedir: No such file or directory

I've looked around enough to see that _filedir is used in many pre-defined (by default) shell functions defined in /usr/share/bash-completion/bash_completion.

I use file-completion without thinking, to the point it's hard for me to figure out the exact thing I am doing when this glitch occurs. Has anyone taken the trouble to dig deeper into this?

  • Does/did that also happen when using the keyboard shortcut ALT-.? – Alex Stragies Jul 9 '16 at 15:41

A simple tracing

First, you can figure out that what actually happen when you using bash completion with cd command:

$ 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

You can see a function _cd will be called when you use completion with cd. So you know that some thing happened inside _cd function causes your $_ variable value had been altered.

Looking into _cd function: (In my Ubuntu 12.04.4, it's in /etc/bash_completion)

# This meta-cd function observes the CDPATH variable, so that cd additionally
# completes on directories under those specified in CDPATH.
    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
        _filedir -d

    if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
        if [[ "$i" == "$cur" && $i != "*/" ]]; then

    return 0

It does many things, causes your old $_ lost. Maybe you have trouble with line _filedir -d. (In my test, I got $_ changed to -d)

To preventing your wanted $_ from losing, you can save its value immediately when you enter _cd function, then restore this value to $_ before leaving _cd:

    local __=$_


    : $__
    return 0

The trick here is :, it means do nothing in bash, and it has one parameter $__ (which is your wanted $_ value), causing $_ is set to old value before you enter _cd function.


It's very difficult to make bash completion does not trashing $_ variable. With above example, you only prevented it from trashing with cd. With others function in bash_completion and all files under /etc/bash_completion.d/, you have to do the same thing. This is not a robust solution.

If you want to get the last parameter of the last command line, try using bash history expansion instead:

$ echo 1 2 3
1 2 3
$ echo !$
echo 3

You've got programmable completion ("bash completion") enabled. That's done by sourcing /etc/bash_completion or /usr/share/bash-completion/bash_completion somewhere in your bashrc. For example, in the skeleton bashrc on jessie:

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion

One of the completions is overwriting $_. The quick workaround would be to not load bash-completion.

Another workaround is to do your filename completions with the complete-filename function instead of the complete function. That'd mean pressing ESC, / or Alt+/ (depending on your terminal setup) instead of Tab. You can change which keys those are bound to with bind or by editing ~/.inputrc.

And, I suppose, file a bug report against bash-completion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.