1

Assume one has the following alias in your .bashrc:

alias docker='sudo docker'

then try to autocomplete docker run -v /tmp/test:/foo … in a bash terminal, starting from docker run -v /tmp| → due to the presence of sudo in the alias, one gets the following distracting behavior:

$ docker run -v /tmpTAB
$ docker run -v /tmp[sudo] password for user: 

and at that point, it is almost impossible to further edit the command line, apart from doing Ctrl+C and restarting.

Are there solutions to overcome that behavior? namely, keep the sudo implied in the alias, but avoid the password prompt when we are just expecting some regular autocompletion.

A solution that is independent of the alias feature would be nice (given the issue presented here also arises when typing any $ sudo command … directly).

2 Answers 2

1

If you're looking to avoid a password prompt on sudo, try the -n option.

The man page for sudo reads:

-n, --non-interactive

Avoid prompting the user for input of any kind. If a password is required for the command to run, sudo will display an error message and exit.

3
  • Thanks but that does not work: try sudo -n docker run -v /tmp[TAB]
    – ErikMD
    Nov 29, 2020 at 22:09
  • On second thought, by setting alias docker='sudo -n docker' first and trying again, the issue does not occur anymore! thank you :)
    – ErikMD
    Nov 29, 2020 at 22:13
  • There is a drawback though: after setting sudo -n in the alias (which is OK at autocompletion time), sudo does not ask for the password any longer (at "run" time). Would you think about some way to fix this, "conditionally"?
    – ErikMD
    Nov 29, 2020 at 22:23
0

Relying on @ApolloXI's advice regarding sudo -n and doing more experimentations, I was able to overcome the drawback I was mentioning in my previous comment.

To sum up, when autocompleting docker … commands, the following code is loaded:

  • From /etc/bash.bashrc: . /usr/share/bash-completion/bash_completion;
  • From /usr/share/bash-completion/bash_completion:
    • __load_completion docker,
    • then . /usr/share/bash-completion/completions/docker;
  • From /usr/share/bash-completion/completions/docker:
    • docker version -f '{{.Client.Experimental}} {{.Server.Experimental}} {{.Server.Os}}, etc.
    • which re-runs the docker command (or the alias, if it exists).

So a working solution would just amount to replace my alias with a bash function, detecting whether it is called from the bash-completion feature. This can be done by reading the BASH_SOURCE array.

As a result, we could adopt the following solution:

docker() {
    if [[ "${BASH_SOURCE[*]}" =~ "bash-completion" ]]; then
        sudo -n docker "$@"
    else
        sudo docker "$@"
    fi
}

or if we want to be able to easily disable the wrapper, write instead:

__docker() {
    if [[ "${BASH_SOURCE[*]}" =~ "bash-completion" ]]; then
        docker "$@"
    else
        sudo docker "$@"
    fi
}

alias docker=__docker

Then, the sudo -n prefix is not necessary anymore, and it is possible to run for example:

$ \docker run --help

You must log in to answer this question.

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