Bash – set -x: tab completion results in messy output when working in debug mode

autocompletebashdebuggingoutputUbuntu

I understand that set -x gets a Bash user into debug mode and I feel that working full time in debug mode will help me handle possible problems better in Bash.

I experience a problem when working with set -x:

When I try to use the native tab completion of my distro (Ubuntu 16.04) to complete a directory's name, I get a very long, messy output.

For example, $PWD is /var/www/html/ and I run either of these:

cd ~/u[tab completion to complete u to ulcwe]

cd ~ && cd u[tab completion to complete u to ulcwe]

In both examples I'll get a very long and messy output:

+ return 0
+ local -a toks
+ local quoted x tmp
+ _quote_readline_by_ref '~/u' quoted
+ '[' -z '~/u' ']'
+ [[ ~/u == \'* ]]
+ [[ ~/u == \~* ]]
+ printf -v quoted '~%q' /u
+ [[ ~/u == *\\* ]]
+ [[ ~/u == \$* ]]
++ compgen -d -- '~/u'
+ x='~/ulcwe'
+ read -r tmp
+ toks+=("$tmp")
+ read -r tmp
+ [[ -d != -d ]]
+ [[ -n '' ]]
+ [[ 1 -ne 0 ]]
+ compopt -o filenames
+ COMPREPLY+=("${toks[@]}")
+ return 0
lcwe/

Note the lcwe in the end.

The above output is just part of a much larger output.

How could I keep working in debug mode full time (set -x) but without all that output when performing tab completion?

Best Answer

This is due to the programmable completion feature of the shell that you are using.

If you're happy with basic tab completion for commands and filenames in bash, then running

complete -r

in your ~/.bashrc will remove any "fancy" (programmable) completion that involves calling functions etc. in the current shell's environment.

Basic filename completion (like what you're doing in the examples in your question) will still work after turning off programmable completion.

Programmable completion is available in some shells and allows one to hook up callback functions that examine the state of the command line etc. to figure out what the possible strings that the user might want to insert next might be. For example, typing ssh and then Space and Tab may invoke a function that parses your ~/.ssh/config file for possible hostnames to connect to, or typing git checkout and then Space and Tab may cause a function to run a git command to figure out what branches are available in the current repository.

Some users rely on programmable completions for speed and/or productivity reasons, but yes, if you have set -x active in the interactive shell session, these actions would produce trace output in the terminal.


I've never been a friend of programmable completion in any shell as I don't want a simple Tab press to do "magic behind my back" in all sorts of interesting ways. I also think it's a bit lazy, but that's definitely only my personal opinion.

Related Question