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

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?


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.

  • Thx. I know what is a callback a function (a function that is called back by another function) but I don't know what do you mean by "hook up". Also dear Kusalananda, please add an opening statement similar to "The behavior you're witnessing does with programmable completion which is a feature of tab completion once could turn on or off". Thanks again! – user9303970 Feb 27 '18 at 19:58
  • BTW, just for the sake of mentioning it if someone wants it: How do you revert complete -r? I tried complete +r and also reboot but in both cases no revert was done. – user9303970 Feb 27 '18 at 22:22
  • @user9303970 The only way to revert the change is to start a new shell session that does not do complete -r. This would source the default shell startup files, some of which initializes the programmable completions. – Kusalananda Feb 28 '18 at 6:42
  • @user9303970 A callback function, in the general sense (it's used in other settings as well, with other programming languages, for example in some parsers etc.) is a user-defined function that you "install" or "hook up" or "register" with a system to be called under certain circumstances. A simple example, which i believe could be called a "callback function" is the comparison function used with the standard C library's qsort() routine. qsort() can sort any type of C structure, but needs help from a user-supplied comparison function to do the actual comparisons. – Kusalananda Feb 28 '18 at 6:47
  • 1
    Sorry Kusalanada, I misled myself and you. The reboot took me out of set -x hence I didn't see the programmable completion that came back with the new set -x mode. I will now put set -x && complete -r in ~/.bashrc and will have both of them working harmoniously. Sorry again, please forgive me for this. I should have think more on this. – user9303970 Mar 1 '18 at 10:10

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.