Home / Alt manpages / dh_bash-completion(1)

  • dh_bash-completion(1)
  • User command
  • linux

Package Bash Completions with dh_bash-completion

Your tool has forty subcommands and nobody remembers them, so you want tab completion shipped inside the .deb. dh_bash-completion puts the file in the right directory at build time, and you can prove it worked without touching your own Bash setup.

Allow about fifteen minutes for a small package. You need a Debian package source tree, debhelper, and the bash-completion package available as a build dependency.

This guide describes the installed dh_bash-completion from bash-completion version 1:2.11-8. The local manual page is dated 18 September 2023. You package the files in your source tree first. Installing the finished package on a machine is a separate, privileged job.

1. Enable the debhelper addon

Add bash-completion to the source package's build dependencies. In a conventional Debian control file the relevant line is:

Build-Depends: debhelper, bash-completion

Keep the debhelper compatibility level appropriate for your package. The dependency that matters here is bash-completion, because that package provides dh_bash-completion.

Next, make the debhelper sequence use the addon. If debian/rules already has a dh invocation, append the option rather than creating a second build path:

#!/usr/bin/make -f

%:
	dh $@ --with bash-completion

The manual requires both parts: the build dependency and --with bash-completion. Without the addon the helper is not in the sequence, even if its executable is installed.

Checkpoint

Confirm the dependency and the option are present before you edit any completion files.

$ grep -E 'bash-completion|debhelper' debian/control
$ grep 'dh .*--with bash-completion' debian/rules

2. Choose the completion file format

The helper looks for a file named after the binary package, using this pattern:

debian/PACKAGE.bash-completion

Replace PACKAGE with the binary package name from the Package: field in debian/control. That is not necessarily the source package name. For a package called mytool, create debian/mytool.bash-completion.

Two shapes are supported. The first is a proper Bash completion snippet, installed as one completion file named after the binary package:

_mytool_complete()
{
    COMPREPLY=()
}

complete -F _mytool_complete mytool

This is a snippet, not a script to run at package installation. It defines a completion function and registers it with Bash's complete builtin.

The second shape is a list of source files. Each non-empty, non-comment line names a file, optionally followed by the completion name to install:

src/mytool-completion
src/admin-completion  mytool-admin

Here is how the two lines land:

  • First line. Installed as mytool-completion, the source file's basename.
  • Second line. Installed under the explicit name mytool-admin.
  • Paths. Sources are resolved from the source directory. Installed files go below /usr/share/bash-completion/completions.

3. Keep the list unambiguous

Warning

Use the list format only when every referenced path exists at build time. A missing or mistyped path can make the installed helper fall back to treating the list file as a single completion snippet, which is not what you wanted.

Comments and blank lines are allowed in a list, but keep each mapping on one line:

# Main command
src/mytool-completion

# Administrative subcommand
src/admin-completion mytool-admin

If you only need one completion file, the snippet format is less error-prone. In a snippet, keep prose comments valid as Bash comments so they cannot be mistaken for shell syntax.

Checkpoint

Verify the package name and every list path without changing anything.

$ dpkg-parsechangelog -S Source
$ sed -n '/^Package:/p' debian/control
$ test -f debian/mytool.bash-completion
$ test -f src/mytool-completion

4. Build the package

Run your normal Debian package build from the source root. For a local test build that is commonly:

$ dpkg-buildpackage -us -uc

The flags skip signing the test source and binary packages. They install nothing. Let the build finish before you inspect the output. The completion file is part of the package payload, not a file copied into /usr/share on the build host.

If the build fails because a build dependency is missing, install or provide the declared dependencies through your normal packaging environment. Do not work around it by copying dh_bash-completion into the source tree.

5. Verify the archive contents

Inspect the generated binary package with dpkg-deb. Replace the placeholder archive name with the exact file your build produced:

$ dpkg-deb -c ../mytool_1.0-1_amd64.deb | grep 'usr/share/bash-completion/completions/'
-rw-r--r-- root/root       123 2026-09-23 02:30 ./usr/share/bash-completion/completions/mytool-completion

Timestamp and size will differ. The useful part is the path and filename:

  • Snippet format. Expect the binary package name as the installed completion filename.
  • List format. Expect the basename or explicit name chosen on each line.

You can read the file content without installing the package:

$ dpkg-deb --fsys-tarfile ../mytool_1.0-1_amd64.deb \
    | tar -xOf - ./usr/share/bash-completion/completions/mytool-completion
_mytool_complete()
{
    COMPREPLY=()
}

This archive check is read-only and needs no sudo. Installing the package later may need root and will change the target machine's filesystem, so do that separately, after you have reviewed the package.

6. Recover from a wrong completion

If the archive has the wrong name or content, do not repair /usr/share/bash-completion by hand. Correct debian/PACKAGE.bash-completion or the referenced source file, remove only the affected build output if your workflow needs a clean rebuild, and build again.

Recovery

If you already installed a bad package, rebuild a corrected one and upgrade through your normal package-management process. To remove the package, use your normal Debian removal command, but remember that removal also deletes the packaged completion file and may affect users who rely on it. The source tree is where the durable fix belongs.

A successful build proves the file was packaged. It does not prove the completion function behaves for every command line. Test the snippet in a disposable shell or package test environment after you have checked the archive.

Done means

  • Build dependency declared. bash-completion is in Build-Depends.
  • Addon enabled. debian/rules passes --with bash-completion to dh.
  • Name matches. The file name matches the binary package name.
  • Format intended. The snippet or file list uses the format you meant for this package.
  • Archive checked. dpkg-deb -c shows the expected file below /usr/share/bash-completion/completions.
  • System untouched. No system completion directory was edited during the build.