'List manually installed apt packages on Debian 10 (Buster)
It was always nice to see which packages I manually installed using apt install.
Because I could then remove the packages I no longer need.
But I can't find a command working on Debian 10 (Buster) with APT version 1.8.2.
Is there a command showing all manually packages without their dependencies?
I tried the commands in these posts:
Solution 1:[1]
This Bash command will print all manually installed packages minus the ones that came from your Debian installation (in other words, the packages that you installed with apt install
):
sudo grep -oP "Unpacking \K[^: ]+" /var/log/installer/syslog \
| sort -u | comm -13 /dev/stdin <(apt-mark showmanual | sort)
It was tested in Debian 10 (Buster). sudo
is needed to search through /var/log/installer/syslog
. You could also save this installer package list somewhere else if you don't want to use sudo
every time.
Solution 2:[2]
You can get a list of apt/apt-get installed packages by grepping /var/log/apt/history.log*
grep_apt_history.bash:
#!/usr/bin/env bash
# current apt history
grep "apt.* install" /var/log/apt/history.log | grep -v broken \
| grep -Po 'install\s\K.*' | sort -u
# zipped apt history
gzip -cd $(find /var/log/apt -name "history.log.[0-9]*.gz") \
| grep "apt.* install" | grep -v broken | grep -Po 'install\s\K.*' | sort -u
parse_apt_install.py:
#!/usr/bin/env python3
import sys
installed_packages = []
avoid = ['--no-install-recommends', '--yes', '-y', '--reinstall']
for line in sys.stdin:
if ' ' in line:
packages = line.split(' ')
for package in packages:
if not package in avoid:
installed_packages.append(package.strip('\n'))
else:
stripped = line.strip('\n')
if not './' in stripped:
installed_packages.append(stripped)
for package in sorted(installed_packages):
print(package)
The python script will remove packages installed locally './'
Usage:./grep_apt_history.bash | ./parse_apt_install.py
Solution 3:[3]
Wrote this script to replay the apt history logs, producing a list of what was installed manually and is still installed. A little hacky and there may be undiscovered exceptions, but it works on Debian 11 and Mint 20. Explanations are in the code comments.
#!/bin/bash
PROGRAM_LIST=() # array to hold programs
EARLIEST_RECORD="$( zgrep . /var/log/apt/history.log* | grep Start-Date | sed 's@Start-Date: @@g; s@ @ @g;' | sort -d | head -n 1 )" # find earliest log entry (zgrep handles gzipped and uncompressed input)
prepare_sorted_log() {
# select any operations *requested*, plus precededing two lines (date and command)
# select only relevant operations and preceding line (date)
# collapse to one line
# separate individual actions using grep's group separator, compress spaces, remove starting text
# reduce to date, action, and programs only
# sort by date (first columns)
# remove apt* flags and leading text
zgrep -h Requested /var/log/apt/history.log* -B 2 \
| egrep -B1 ' (install|remove|purge)' \
| tr '\n' ' ' \
| sed -r 's@ -- @\n@g; s@ @ @g; s@Start-Date: @@g;' \
| sed -r 's@Commandline: .*(install|remove|purge)(.*)@\1\2@g;' \
| sort \
| sed -r 's@ \-+[A-Za-z]+( |$)@ @g; s@.*(install|remove|purge) @\1 @g;'
}
install() {
for program in ${@}; do
[[ "${program}" =~ DPkg.* ]] && return # filter exceptions (add more with |)
echo -n "Found installation of ${program}; adding to list ... "
PROGRAM_LIST+=(" ${program} ") && echo "done" || echo "ERROR" # add to array since install was requested
done
}
remove() {
for program in ${@}; do
echo -n "Found removal of ${program}; removing from list ... "
PROGRAM_LIST=( "${PROGRAM_LIST[@]/ ${program} }" ) && echo "done" || echo "ERROR" # remove from array since remove or purge was requested
done
}
purge() {
remove ${@} # remove and purge are the same for our purposes
}
while read line; do
eval "${line}" # run function based on action
done <<< "$( prepare_sorted_log )" # read prepared and sorted log
echo -e "\nPrograms installed manually and not subsequently removed (since ${EARLIEST_RECORD}):\n$( echo "${PROGRAM_LIST[@]}" | tr ' ' '\n' | sort -u )" # display sorted list
echo -e "\nInstallation paste:\n\napt install$( echo "${PROGRAM_LIST[@]}" | sed -r 's@ +@ @g' )" # display command to install (e.g., on new system)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter Mortensen |
Solution 2 | |
Solution 3 | user108151 |