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


2 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