18

I made an alias to save some keystrokes with working with systemd:

$ alias sctl='systemctl' 

However, this breaks tab completion for the subcommands. Is it possible to alias a command without breaking tab completion?

3 Answers 3

27

First find out which complete-function is used for the systemctl command:

complete | grep " systemctl$" 

The output looks like this:

complete -F _functionname systemctl 

Then use:

complete -F _functionname sctl 

To register the function for the completion of your alias.

Now, when you type sctl <tab><tab>, the same suggestions as when you type systemctl will appear.

10
  • As extra note: Use -c instead of -F if you need package autocompletion for your alias. Commented May 21, 2018 at 2:36
  • 7
    Note this only works for autocompletion on the command itself, not on the command + args. Eg if you alias='command arg1 arg2' then the above will produce completion as though you had just typed command, not command arg1 arg2. Commented Feb 14, 2020 at 14:00
  • This was giving me bash: completion: function `_systemctl' not found when typing sctl <tab><tab>. I fixed this by adding source /usr/share/bash-completion/completions/systemctl, which defines the function, before complete -F _systemctl sctl. Commented May 23, 2020 at 12:47
  • about loading completion functions, _completion_loader <commandname> is sometimes the best way for that. I wanted to note that this answer doesn't always work. I found some completions that depend on _parse_help, they call help on the command itself. and in that context the alias apparently does not exist, so no help-derived completions work. Commented Sep 25, 2022 at 20:32
  • @creanion Aliases don't work with _parse_help but shell functions should. Commented May 6, 2023 at 20:53
6

After installing this tool, you can do it like this:

  • In ~/.bash_profile:

    alias sctl='systemctl' 
  • In ~/.bash_completion:

    complete -F _complete_alias sctl 
  • Type sctl <tab> to show systemctl commands:

    $ sctl <Tab> add-requires add-wants cancel cat condreload ... 
0

I hacked this to have completion also work for systemctl+args. I copied some parts of the source code of bash-completion for systemctl to manage that (/usr/share/bash-completion/completions/systemctl).

alias ssr='sudo systemctl restart' alias sss='sudo systemctl status' alias ssp='sudo systemctl stop' # Load necessary functions in bash-completion's source code for systemctl (get_*_units) source /usr/share/bash-completion/completions/systemctl # Manually recreate some functions _systemctl_status() { comps=$( __get_non_template_units --system "${COMP_WORDS[1]}" ) compopt -o filenames COMPREPLY=( $(compgen -o filenames -W '$comps') ) return 0 } _systemctl_restart() { comps=$( __get_restartable_units --system "${COMP_WORDS[1]}" ) compopt -o filenames COMPREPLY=( $(compgen -o filenames -W '$comps') ) return 0 } _systemctl_stop() { comps=$( __get_stoppable_units --system "${COMP_WORDS[1]}" ) compopt -o filenames COMPREPLY=( $(compgen -o filenames -W '$comps') ) return 0 } complete -F _systemctl_restart ssr complete -F _systemctl_status sss complete -F _systemctl_stop ssp 

This can easily be expanded for other systemctl commands, just look for the right get_*_units command in the source file and copy my examples.

I also tried to modify the $COMP_WORDS array to get some general solution working for all commands, but to no avail.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.