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
Eliah Kagan
  • 117,780
keturn
  • 1,257
  • 4
    If you are affected by this bug please consider voting under the following url (requires login): https://bugs.launchpad.net/ubuntu/+source/bash/+bug/778627/+affectsmetoo – cripton May 24 '12 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... – Jonatan Öström Jun 29 '20 at 22:06
  • 4
    As of August 2020, this bug still exists in Ubuntu 20.04, bash 5.0-6ubuntu1.1. – Naghi Aug 23 '20 at 05: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 '22 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 '23 at 19:46

8 Answers8

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.

Eliah Kagan
  • 117,780
  • 2
    a version of bash with direxpand is making its way into Precise (12.04): See https://bugs.launchpad.net/bugs/778627 – keturn Mar 31 '13 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 '14 at 06:17
  • 1
    @jozxyqk Did you ever find a way to get that no-path-expansion feature? – Ungeheuer Apr 08 '19 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 '19 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 '19 at 14:14
  • I don't know about Ubuntu, direxpand has its own problems in Fedora. – Jonathan Wakely Dec 12 '19 at 11:49
  • The bad thing is that you have to re-set direxpand option in every new termnal. – Naghi Aug 23 '20 at 10:40
  • I summarize the solution as following: 1- open ~/.bashrc in an editor 2- add this line at the end of the file shopt -s direxpand. 3- save the file, close and open your terminal again; the problem is solved! – Naghi Aug 23 '20 at 14:21
  • @jozxyqk Seems worth mentioning that this is exactly how zsh works out of the box. Seriously thinking of switching now. – Luke Maurer Feb 05 '21 at 21:16
  • @jozxyqk you write "I'm currently using bash 4.4.19 on Ubuntu 18.04 and it just works. Not sure when this changed" If you have the package bash-completion installed, it works because of an Ubuntu patch for this package, specifically this one – philb May 17 '22 at 21:29
42
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

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
guntbert
  • 13,134
mba
  • 61
  • 1
    In 12.04 GNU bash, version 4.2.25 this suggestion gives the error: compopt: noquote: invalid option name – arielf Nov 14 '15 at 00: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>/') – Jonathan Wakely Dec 12 '19 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 08 '21 at 06: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). – Jonathan Wakely Aug 06 '21 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.

Eliah Kagan
  • 117,780
rsn86
  • 171
  • 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 '22 at 20:02
2

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

for example :

cd /bin
echo ~+/ls
/bin/ls
Tony
  • 141
1

Disabling the shell option 'complete_fullquote' does the job:

shopt -u complete_fullquote
  • $ shopt -u complete_fullquote -bash: shopt: complete_fullquote: invalid shell option name – Anton Gorev Sep 05 '19 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. – nishanthshanmugham Sep 09 '20 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...

philb
  • 162
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.

jozxyqk
  • 1,111