20

The new apt command, present in Ubuntu since 14.04, seems to be a really useful intersection of functionality between apt-get and apt-cache but the current version of bash-completion doesn't know about it... Which makes it a lot harder to use.

Is there a quick way to add this functionality to Bash to make the apt command easy to use?

26

This is an omission in the bash-complete package, not apt. It just seems a completion doesn't exist yet, so I've scrapped together what I can for the apt command (it's not the best documented command that's ever existed!)

The following is an adaptation from the existing apt-get completion (with elements stripped out and bits added from apt-cache's completion). Run sudoedit /usr/share/bash-completion/completions/apt and paste in the following:

# Debian apt(8) completion                             -*- shell-script -*-

_apt()
{
    local cur prev words cword
    _init_completion || return

    local special i
    for (( i=0; i < ${#words[@]}-1; i++ )); do
        if [[ ${words[i]} == @(list|search|show|update|install|remove|upgrade|full-upgrade|edit-sources|dist-upgrade|purge) ]]; then
            special=${words[i]}
        fi
    done

    if [[ -n $special ]]; then
        case $special in
            remove|purge)
                if [[ -f /etc/debian_version ]]; then
                    # Debian system
                    COMPREPLY=( $( \
                        _xfunc dpkg _comp_dpkg_installed_packages $cur ) )
                else
                    # assume RPM based
                    _xfunc rpm _rpm_installed_packages
                fi
                return 0
                ;;
            *)
                COMPREPLY=( $( apt-cache --no-generate pkgnames "$cur" \
                    2> /dev/null ) )
                return 0
                ;;
        esac
    fi

    case $prev in
        -c|--config-file)
             _filedir
             return 0
             ;;
        -t|--target-release|--default-release)
             COMPREPLY=( $( apt-cache policy | \
                 command grep "release.o=Debian,a=$cur" | \
                 sed -e "s/.*a=\(\w*\).*/\1/" | uniq 2> /dev/null) )
             return 0
             ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d -f -h -v -m -q -s -y -u -t -b -c -o
            --download-only --fix-broken --help --version --ignore-missing
            --fix-missing --no-download --quiet --simulate --just-print
            --dry-run --recon --no-act --yes --assume-yes --show-upgraded
            --only-source --compile --build --ignore-hold --target-release
            --no-upgrade --force-yes --print-uris --purge --reinstall
            --list-cleanup --default-release --trivial-only --no-remove
            --diff-only --no-install-recommends --tar-only --config-file
            --option --auto-remove' -- "$cur" ) )
    else
        COMPREPLY=( $( compgen -W 'list search show update install 
            remove upgrade full-upgrade edit-sources dist-upgrade 
            purge' -- "$cur" ) )
    fi

    return 0
} &&
complete -F _apt apt

# ex: ts=4 sw=4 et filetype=sh

Then run source ~/.bashrc to load the completion. Then apt show firef + Tab should complete.

This may offer you options that just don't exist any more. I think I've nailed the main commands (which might change in time) but at the very least it'll help you with the common commands: list search show update install remove upgrade full-upgrade edit-sources dist-upgrade purge.

Obviously, if a bash-completion maintainer wants to nab the above, you're welcome to it under GPL (though I'd be tempted to start from fresh once apt is documented!)

  • 8
    Open a bug and submit this as a patch! – Jorge Castro Apr 10 '14 at 18:04
  • Do you have any idea on how to use this answer with zsh? – Exeleration-G Jun 11 '14 at 10:43
  • any word on where to "me too" this on launchpad? – Mateo May 2 '15 at 17:14
1

Why not use the original bash-completion?

Try this script. It will download and install the bash-completion on ~/tmp/bash-completion.

#!/bin/bash
echo -en "\e]2;Updating bash completion...\a"

katalog="~/tmp/bash-completion"

if [ ! -d "$katalog" ]; then
   mkdir -p $katalog
   cd $katalog
   cd ..
   git clone git://git.debian.org/git/bash-completion/bash-completion.git
   cd $katalog
   autoreconf -i
   ./configure
   make
   sudo make install
else
   cd $katalog
   if [ `git log --pretty=%H ...refs/heads/master^` != `git ls-remote origin -h refs/heads/master |cut -f1` ]; then
      git pull
      autoreconf -i
      ./configure
      make
      sudo make install
   else
      echo "Bash-completion is already up to date!"
   fi
fi

You start using it with command . ~/tmp/bash-completion/bash_completion.sh, which can be put into ~/.bashrc file, or - better yet - symlink it into some file in the /etc/profile.d/ directory. Uninstall the original bash-completion, so you wouldn't end up loading both at the same time.

  • I hadn't thought of this but they also don't seem to have an apt completion yet – Oli Apr 11 '14 at 11:13
  • 1
    @Oli Well, I guess they do. There are files aptitude, apt-get and apt-cache. What exactly do you mean by apt completion? – Adam Ryczkowski Apr 11 '14 at 20:57
  • 3
    Per my opening question, apt is a brand new(ish) command that's in Trusty. It has some of apt-get, some of apt-cache... All with a little bit of extra flourish in one place. – Oli Apr 14 '14 at 17:50
  • @Oli Oh, you are right! I didn't know about it. And - bash-completion doesn't support it out of the box so far. Fortunately it wouldn't be that difficult to write a plugin, so you can expect one soon. Chances are, that using my script you would be among the first, who can use it. – Adam Ryczkowski Apr 14 '14 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.