Skip to content

apt-get: long "--" option completion (e.g. --no-install-recommends) unreachable after subcommands like install/remove/purge #1690

Description

@AbraxasDMG

Description

In completions/apt-get, the _apt_get() function contains two separate
completion code paths:

  1. A "special subcommand" branch, entered via if [[ -v special ]]; then ... fi,
    which fires whenever a subcommand such as install, remove, purge,
    autoremove, source, build-dep, download, or changelog is found
    anywhere earlier on the command line.
  2. A generic long-option branch further down:
    if [[ $cur == -* ]]; then
        COMPREPLY=($(compgen -W '--no-install-recommends --install-suggests
            --download-only --fix-broken ... ' -- "$cur"))
    fi

The problem is that the install) arm inside the "special" case block ends
with ;;& (fall-through-and-retest), so execution always continues into the
final catch-all arm:

*)
    COMPREPLY+=($(_xfunc apt-cache _apt_cache_packages))
;;

...which attempts package name completion, and the whole if [[ -v special ]]
block ends with an unconditional return.

As a result, whenever a subcommand like install is present anywhere on the
command line, the function returns before ever reaching the generic
[[ $cur == -* ]] branch further down — so long options can never be
completed after a subcommand
, even though the option list clearly exists
in the script and is intended to work.

Steps to reproduce

apt-get install --no<TAB><TAB>

Expected: completion offers --no-install-recommends, --no-download,
--no-upgrade, --no-show-upgraded, etc. (all present in the hardcoded
compgen -W list later in the function).

Actual: nothing is completed. The shell instead silently attempts
_apt_cache_packages (package-name completion) against --no, which
naturally matches no package, so COMPREPLY stays empty.

This affects any apt-get subcommand handled by the special case
(install, remove, purge, autoremove, source, build-dep,
download, changelog) — i.e. exactly the subcommands people most commonly
want to pass options like --no-install-recommends, --purge,
--dry-run, etc. to.

Environment

  • bash-completion version: 1:2.11-8 (also reproducible by inspection on
    upstream tags 2.9, 2.10, and 2.11)
  • apt/apt-get version: 2.8.3
  • OS: Linux Mint 22.3 (Cinnamon), based on Ubuntu 24.04 "noble"
  • GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions