103

I have this on the command line:

ln -sf $PWD/wine-

and then I hit Tab to complete the filename. In earlier versions of Ubuntu, this worked just fine to complete the wine- filename (and as a side-effect $PWD would be expanded at that time). But now it turns it in to

ln -sf \$PWD/wine-

which isn't what I meant at all and doesn't complete anything as the file does not literally start with $.

How do I get completion back to the less broken behaviour?

set tells me these are my current settings:

BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
5
  • 4
    If you are affected by this bug please consider voting under the following url (requires login): bugs.launchpad.net/ubuntu/+source/bash/+bug/778627/…
    – cripton
    May 24, 2012 at 17:03
  • 6
    How can this still be a there in 2020? If it understands that it's a path variable so that it expands the filename (which it does for me) it should understand to not escape the $ that makes it a path variable... Jun 29, 2020 at 22:06
  • 4
    As of August 2020, this bug still exists in Ubuntu 20.04, bash 5.0-6ubuntu1.1.
    – Naghi
    Aug 23, 2020 at 5:21
  • "This" is several bugs/ behaviour changes across both Bash itself and bash-completion, and the specific patches that each Linux distributions carry for both of these...
    – philb
    May 17, 2022 at 22:21
  • It looks like in ubuntu 22.04, you need to remove or comment out the completion code at the bottom of ~/bashrc. I then put my options in .bash_aliases.
    – Juan
    Aug 16, 2023 at 19:46

8 Answers 8

95

I've found that bash versions >= 4.2.29 have a new direxpand shopt setting. (See man docs/bash.1 if you check out a new bash, or see bash.1 from line 8951)

If one uses Quantal Quetzal 12.10 or otherwise gets hold of (or checks out and builds) a new bash, then:

shopt -s direxpand

Gives me the behavior I want, need and love.

Workaround: In the meantime, Ctrl+Alt+E instead of Tab does what I want too. But is awkward.

BTW, There are several threads called "bash tab variable expansion question?" in gnu.bash.bug. From reading them, I found the info here.

10
  • 2
    a version of bash with direxpand is making its way into Precise (12.04): See bugs.launchpad.net/bugs/778627
    – keturn
    Mar 31, 2013 at 19:48
  • 21
    Would be even better if I didn't have my huge path expanded and could continue using an un-escaped variable with completion.
    – jozxyqk
    Aug 28, 2014 at 6:17
  • 1
    @jozxyqk Did you ever find a way to get that no-path-expansion feature?
    – Ungeheuer
    Apr 8, 2019 at 16:40
  • @Ungeheuer I'm currently using bash 4.4.19 on Ubuntu 18.04 and it just works. Not sure when this changed.
    – jozxyqk
    Apr 26, 2019 at 22:12
  • 9
    user3080602's answer below worked for me - shopt -u progcomp solves the issue without expanding the variable to it's value
    – Gilthans
    Nov 27, 2019 at 14:14
41
shopt -u progcomp

This fixed it for me, it also removed a lot of "intelligent" completion options which I have found get in the way by not completing files that I know are there because the stupid thing thinks I don't want them as arguments to a particular command. ARRRGH

4
  • 1
    This did it for me! It doesn't escape the variable, nor does it expand it. Thanks!
    – Gilthans
    Nov 27, 2019 at 14:12
  • 1
    This (u)nsets the shell option progcomp. See here for more info.
    – user643722
    May 28, 2020 at 10:48
  • 1
    This works for the paths, but for example when using make seeing the make-targets is quite convenient, which is lost with this setting. Jun 29, 2020 at 22:07
  • 2
    I also lost support for git tab-completion (e.g. git checkout + Tab, for branch names). Otherwise, it was nice.
    – Carolus
    Jun 4, 2021 at 14:10
6

search _filedir() in the top level bash_completion script and change the line

compopt -o filenames 2>/dev/null

to

compopt -o filenames -o noquote 2>/dev/null
4
  • 1
    In 12.04 GNU bash, version 4.2.25 this suggestion gives the error: compopt: noquote: invalid option name
    – arielf
    Nov 14, 2015 at 0:28
  • To avoid changing the root-owned script, I'm using this in my .bash_profile: eval $(type -a _filedir | tail -n +2 | sed 's/compopt -o filenames 2>/compopt -o filenames -o noquote 2>/') Dec 12, 2019 at 11:50
  • 1
    It now removes backslashes from manually-escaped filenames: ls file\ w [tab] → ls file with space where the expected result is ls file\ with\ space
    – iBug
    Mar 8, 2021 at 6:41
  • In my comment above, the argument to eval should be quoted, and it can be simplified to eval "$(declare -f _filedir | sed 's/compopt -o filenames 2>/compopt -o filenames -o noquote 2>/')" (but this does indeed have the problem that iBug noted in the comment immediately above, so you need to say ls "file w[tab] to expand usefully). Aug 6, 2021 at 12:18
5

On GNU bash, version 4.2.46(2)-release, the options complete_fullquote and noquote aren't available. The cdable_vars option works on cd only; direxpand expands the variable.

What worked best for me was:

shopt -u progcomp

It worked on other commands, besides cd, preserving the variables instead of expanding them.

1
  • 1
    Useless. It completely disables the intelligent completion from /usr/share/bash-completion/completions/ directory. So, now 99% of the things you will type manually.
    – Max_Payne
    Mar 19, 2022 at 20:02
2

For those (like me) with 12.04 can use ~+ instead of $PWD...

for example :

cd /bin
echo ~+/ls
/bin/ls
1

Even with the updated bash, I was finding $ still gets escaped.

  • Removing the bash-completion (1:2.1-3.fc20) package
  • or simply not sourcing /etc/bashrc from ~/.bashrc seemed to fix it.

I suspect I'll now be missing some features I'm normally used to but haven't noticed any yet.


Alternative (at least for Fedora 26), add export BASH_COMPLETION_VERSINFO=0 before sourcing /etc/bashrc. This makes the problematic script think its already been sourced.

1

Disabling the shell option 'complete_fullquote' does the job:

shopt -u complete_fullquote
2
  • $ shopt -u complete_fullquote -bash: shopt: complete_fullquote: invalid shell option name Sep 5, 2019 at 20:34
  • 2
    The option is available for me in bash v5.0.17, but setting it results in undesirable behavior. When I tab-complete "vim ~/.ba" it adds a backslash like "vim \~/.bashrc", which seems similar to the issue OP had in the question. Sep 9, 2020 at 12:14
1

If you do not care for programmable completion (usually installed by bash-completion), then any method mentioned here to disable those will do (like shopt -u progcomp).

If you want Bash to expand the variable when you type TAB, then shopt -s direxpand will do.

If you do not want to use shopt -s direxpand, and want to keep programmable completions from bash-completion, and you have root access, you can apply the same patch as Ubuntu applies, i.e. this patch.

If you do not have root access you can disable the system bash-completion (see bash-completion's README and install a patched version in your $HOME (download and extract the tarball and --configure --prefix=$HOME or similar)

EDIT the above is valid for Bash 4.4.19. It seems Bash 5.0 and above break the whole thing again...

1
  • Is this Ubuntu patch coming to newer version of Ubuntu?
    – Moberg
    Dec 4, 2023 at 15:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .