In my example I start typing sudo su dkay...<tab>... and the command hangs for about a minute before tab completing to sudo su dkayton.

I got advised to use strace to find out what is happening.

Any ideas on how to pass the underlying commands of tab completion to strace?

What I tried:

I run top in one shell to monitor the processes. I then hit tab immediately after sudo su dkay in another shell.

Then as quick as I could, I copied the PID of the bash process that resulted to sudo strace -pXXX -tfo /tmp/strace.log in a third shell, where XXX is the PID copied.

It still managed to catch more than 2mb of logs. I repeated it twice and was more successful the second time.

I am looking for a more automatic way of completing this.

1 Answer 1


(Assuming you're using Linux) Use echo $$ to get the PID of your current shell. Open a new terminal, and run:

sudo strace -fp <PID> -o log

Switch back to the old shell, try tab completion. Then switch to the new terminal and press CtrlC to end strace. The output will be in the file named log. You could also run the strace command in the same shell (first authenticating to sudo for caching credentials):

sudo -v
sudo strace -fp $$ -o log &

And then try tab completion. To kill it, fg, followed by CtrlC.

However, if you're using bash, it might be better to try getting verbose debug output from it first:

set -o functrace xtrace

And then try tab completion. You should everything that the completion function executes in the output that follows. For example:

bash-5.0$ set -o xtrace functrace
bash-5.0$ PS4=' ${BASH_SOURCE}:${FUNCNAME}:$LINENO: '
bash-5.0$ sudo su  /usr/local/share/bash-completion/bash_completion:_completion_loader:3: local cmd=sudo
 /usr/local/share/bash-completion/bash_completion:_completion_loader:5: __load_completion sudo
 /usr/local/share/bash-completion/bash_completion:__load_completion:2: dirs=(${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions)
 /usr/local/share/bash-completion/bash_completion:__load_completion:2: local -a dirs
 /usr/local/share/bash-completion/bash_completion:__load_completion:3: local 'OIFS=
' IFS=: dir cmd=sudo compfile
 /usr/local/share/bash-completion/bash_completion:__load_completion:2021: for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}
 /usr/local/share/bash-completion/bash_completion:__load_completion:5: dirs+=($dir/bash-completion/completions)
 /usr/local/share/bash-completion/bash_completion:__load_completion:2021: for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}
 /usr/local/share/bash-completion/bash_completion:__load_completion:5: dirs+=($dir/bash-completion/completions)
 /usr/local/share/bash-completion/bash_completion:__load_completion:7: IFS='
 /usr/local/share/bash-completion/bash_completion:__load_completion:9: [[ /usr/local/share/bash-completion/bash_completion == */* ]]
  • Thanks for also providing an alternative debugging mechanism. I was able to easily carry out both.
    – dnk8n
    Jun 18, 2019 at 9:02

You must log in to answer this question.

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