How to Fix Missing Tab Completion for service Command in Debian Systems


27 views

When working with Debian systems, you might encounter inconsistent behavior with the service command's tab completion. While one system properly lists all available services from /etc/init.d, another might display files from the current directory instead.

The missing functionality stems from either:

  • Absence of /etc/bash_completion.d/service file
  • Improper loading of bash completion scripts
  • Missing completion function definitions

First check if completion is properly configured:

complete -p | grep service
# Expected output: complete -F _service service

If this returns nothing, the completion isn't set up. If you see an error about missing _service function, the completion script isn't loading properly.

To fix this, you need the bash-completion package:

sudo apt-get install bash-completion

After installation, verify the service completion file exists:

ls -l /etc/bash_completion.d/service
# Should show something like:
# -rw-r--r-- 1 root root 1234 Jan  1  2020 /etc/bash_completion.d/service

If the file exists but completion still fails, try these steps:

# Reload bash completion
source /etc/bash_completion

# Explicitly set completion for service command
complete -F _service service

If you still see function _service' not found errors:

  1. Check the service completion file contains the _service function definition
  2. Verify your bashrc loads completions:
grep bash_completion ~/.bashrc
# Should include something like:
if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

For systems where bash-completion isn't available, you can create a simple workaround:

# Add to ~/.bashrc
_service() {
    local cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $(cd /etc/init.d && compgen -o filenames -G "$cur*") )
}
complete -F _service service

This manual implementation provides basic service name completion without requiring the full bash-completion package.

After implementing any solution:

# Start new shell session
exec bash

# Test completion
service <TAB>

You should now see the expected list of services from /etc/init.d.


On Debian systems, the service command's tab completion functionality is implemented through bash completion scripts. When working properly, pressing TAB after typing service should display all available services from /etc/init.d.

# Expected behavior:
$ service <TAB>
acpid       cron        dbus        networking  ssh         ...

# Problem behavior:
$ service <TAB>
file1  file2  file3  (lists current directory contents instead)

The issue typically occurs when the /etc/bash_completion.d/service file is missing or not properly loaded. This file contains:

# Sample content of /etc/bash_completion.d/service
_service() {
    local cur prev words cword
    _init_completion || return

    COMPREPLY=( $(compgen -W "$(service --status-all 2>&1 | \
        awk '{print $NF}' | sed -E 's/^$$(\+|\-)$$//')" -- "$cur") )
}
complete -F _service service

First check if the completion is properly set up:

$ complete -p | grep service
# Should return:
complete -F _service service

# If nothing returns, the completion isn't registered

Here's how to properly fix the issue:

# 1. Verify the file exists
$ ls -l /etc/bash_completion.d/service

# 2. If missing, copy from a working system or recreate it
$ sudo cp /path/to/working/system/etc/bash_completion.d/service /etc/bash_completion.d/

# 3. Source the completion file
$ source /etc/bash_completion.d/service

# 4. Verify the function exists
$ declare -F _service
# Should return:
_service

# 5. Make it permanent by adding to .bashrc
echo '[ -f /etc/bash_completion.d/service ] && source /etc/bash_completion.d/service' >> ~/.bashrc

If you still see "function '_service' not found" after copying the file:

# 1. Check file permissions
$ sudo chmod +x /etc/bash_completion.d/service

# 2. Ensure bash completion is properly installed
$ sudo apt-get install --reinstall bash-completion

# 3. Check for syntax errors in the completion file
$ bash -n /etc/bash_completion.d/service

# 4. Alternative manual setup
$ sudo tee /etc/bash_completion.d/service <<'EOF'
_service() {
    local cur
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    services=$(ls /etc/init.d/)
    COMPREPLY=( $(compgen -W "${services}" -- ${cur}) )
}
complete -F _service service
EOF