Я хотел бы получить список пакетов, установленных вручную с помощью apt или aptitude, и узнать, был ли установлен пакет foobar вручную или автоматически. Есть ли какой-либо опрятный способ сделать это из командной строки?
В более новых версиях пакета apt существует также команда apt-mark
apt-mark showmanual
apt-mark showauto | grep -iE '^foobar$' выведет «foobar», если пакет был установлен автоматически, ничего в противном случае.
aptitude search '!~M ~i' отобразит пакеты, которые не были установлены автоматически. Очень жаль, что aptitude не будет частью установки по умолчанию на Ubuntu Desktop, начиная с 10.10.
Следующий сценарий распечатает все пакеты, которые не установлены для автоматической установки, и, следовательно, были установлены вручную:
#!/usr/bin/python
try:
import apt_pkg
except ImportError:
print "Error importing apt_pkg, is python-apt installed?"
sys.exit(1)
apt_pkg.init()
STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
auto = set()
tagfile = apt_pkg.TagFile(open(STATE_FILE))
while tagfile.step():
pkgname = tagfile.section.get("Package")
autoInst = tagfile.section.get("Auto-Installed")
if not int(autoInst):
auto.add(pkgname)
print "\n".join(sorted(auto))
он основан на том, как apt-mark печатает автоматически установленные пакеты.
Для Ubuntu 16.04 проверьте файл журнала /var/log/apt/history.log.
Например:
zgrep 'Commandline: apt' /var/log/apt/history.log /var/log/apt/history.log.*.gz
Это не идеально, но неплохо дать понять, что именно Я был установлен вручную. Поместите -B 1 в grep, чтобы увидеть, когда он был установлен.
Пример вывода
Commandline: apt install postgresql-9.5-plv8
Commandline: aptdaemon role='role-install-file' sender=':1.85'
Commandline: apt install task
Commandline: apt autoremove
Commandline: apt install atom
Commandline: apt upgrade
Commandline: apt-get install asciinema
Commandline: apt install iperf3
Commandline: apt upgrade
Commandline: apt-get install chromium-browser
Commandline: apt install joe cpanminus build-essential postgresql libdbd-pg-perl libcrypt-openssl-bignum-perl libcrypt-openssl-rsa-perl libio-socket-ssl-perl libnet-ssleay-perl libssl-dev
Commandline: aptdaemon role='role-commit-packages' sender=':1.2314'
Commandline: apt install git
Commandline: apt install sqlite
Commandline: apt install whois
Commandline: apt install libdbd-pg-perl
Commandline: apt install perl-doc
Commandline: apt upgrade
Не уверен, что это поднимает aptitude или нет. Кажется, он не забирает установки из рабочего стола Ubuntu Software.
Как прокомментировали несколько человек, showmanual apt-mark кажется немного ошибочным (и я сообщил об этом как об ошибке 727799). Когда я его использую, он фактически сообщает о множестве вещей, которые даже не вошли в / var / lib / apt / extended_states (где это должно быть сохранено), а apt-get не регистрирует вещи, установленные в / var / lib / apt / extended_states (только в / var / lib / dpkg / status). Сценарий python от txwikinger выше рисует напрямую из / var / lib / apt / extended_states, но если вы используете его сегодня, синтаксис может не работать (мой только что начал генерировать ошибки с Kubuntu 13.10). Обновленный синтаксис:
#!/usr/bin/python
import sys
try:
import apt_pkg
except ImportError:
print "Error importing apt_pkg, is python-apt installed?"
sys.exit(1)
apt_pkg.init()
STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
auto = set()
tagfile = apt_pkg.TagFile(open(STATE_FILE))
while tagfile.step():
pkgname = tagfile.section.get("Package")
autoInst = tagfile.section.get("Auto-Installed")
if not int(autoInst):
auto.add(pkgname)
print "\n".join(sorted(auto))
Для меня это был очень короткий список из 5 элементов, которые, похоже, тоже не точны.
Чтобы получить список всех пакетов (не установленных, установленных пользователем или установленных по умолчанию для всех PPA), apt использует следующий метод:
apt list [option]
Возможные варианты, полезные для этого:
--installed для отображения только пакетов, установленных в системе (из примерно 50 000 +)
--manual-installed для отображения пакеты, которые были явно установлены командой, либо напрямую, либо как зависимости.
В качестве альтернативы вы можете сделать:
apt list --manual-installed | grep -F \[installed\], чтобы получить список пакетов, которые были получены пользователем команд и их зависимостей, а также получить дополнительную информацию о них, такую как поддерживаемая версия и архитектура (x86, x86_64, amd64, все и т. д.)
После многопользовательской игры мне удалось собрать этот скрипт. Это работает хорошо для меня:
# List of all packages currently installed
current=$(dpkg -l | awk '{print $2}' | sort | uniq)
# List of all packages that were installed with the system
pre=$(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort | uniq)
# List of packages that don't depend on any other package
manual=$(apt-mark showmanual | sort | uniq)
# (Current - Pre) ∩ (Manual)
packages=$(comm -12 <(comm -23 <(echo "$current") <(echo "$pre")) <(echo "$manual") )
for pack in $packages; do
packname=$(echo $pack | cut -f 1 -d ":")
desc=$(apt-cache search "^$packname$" | sed -E 's/.* - (.*)/\1/')
date=$(date -r /var/lib/dpkg/info/$pack.list)
echo "# $desc"
echo "# $date"
echo "sudo apt-get install $pack"
echo -e ""
done
Как сказал Ли Ло, apt-mark showauto должен получить вам полный список вещей, которые будут автоматически установлены.
Теперь, чтобы показать вещи, которые установлены вручную, выясняется, что есть прекрасный простой модификатор поиска для aptitude , Но вы не хотите этого делать. Вы хотите написать огромную команду bash, которая делает некоторые ракетные науки.
Примечание. Это скорее иллюстрация того, как круто вы будете выглядеть, выбирая массивные команды bash всем своим друзьям.
comm -3 <(dpkg-query --show -f '${Package} ${Status}\n' | \n
grep "install ok installed" | cut --delimiter=' ' -f 1) <(apt-mark showauto)
Я разбил его на две строки для удобства чтения. Что это делает?
Сначала мы запрашиваем dpkg для списка установленных пакетов. Мы отфильтровываем те, которые на самом деле установлены (а не только остаточная конфигурация). Мы отбиваем статус. Мы сравниваем этот список с автоматическим списком из apt-mark. Мы раскачиваемся, потому что можем.Если никто не дает вам приятного ответа, используя команду apr-something, вы можете сделать это с трудом. Apt-get сохраняет свою информацию в / var / lib / apt / extended_states. Любой файл, который установлен автоматически, будет добавлен в этот файл. Если вы установите пакет уже в этом файле вручную, пакет останется в этом файле, но с автоматической установкой: 0 во второй строке. Это не удалено.
Примечание. Как и ожидалось, лучшие ответы, которые могут работать, если появились изменения в файлах. Я сохраняю мой на всякий случай, когда информация о местоположении файла полезна.
Я хотел бы дать GUI-решение.
Открыть Synaptic Package Manager Перейти к Status Нажмите Installed (manual)
Это даст список пакетов, установленных вручную с помощью apt или aptitude.
К сожалению, я не смог найти никакой опции в Custom Filters, чтобы выяснить, был ли установлен пакет foobar вручную или автоматически.
Если пакет находится под Installed, но не под Installed (manual), то он был установлен автоматически. Если пакет находится под Installed (manual), он был установлен вручную.
В этом списке будут указаны все установленные вручную пакеты: зависимости, удаленные пакеты, пакеты, установленные во время установки системы.
unopts() {
in=`cat`
echo "$in" | sed -r 's/ --[^ ]+//g;s/ -[^ ]+//g'
}
list() {
cat '/var/log/apt/history.log' |
grep --color=never -v '\-o APT::Status-Fd=4 \-o APT::Keep-Fds::=5 \-o APT::Keep-Fds::=6' |
egrep --color=never "Commandline: apt-get.* $1" |
sed -r "s/Commandline: apt-get//;s/ $1//" |
unopts |
tr ' ' '\n' |
sed '/^$/d'
}
hapt() {
tmp=`mktemp -d`
installed=$tmp/installed
deleted=$tmp/deleted
dpkg=$tmp/dpkg
list 'install' > $installed
list '(remove|purge|autoremove)' > $deleted
dpkg --get-selections |
grep -v 'deinstall' |
cut -f 1 > $dpkg
while read package
do
sed -i "0,/$package/{//d;}" $installed
done < $deleted
while read package
do
if [ -z "`grep --color=never "^$package$" $dpkg`" ]
then
sed -i "0,/$package/{//d;}" $installed
fi
done < $installed
cat $installed
rm -r $tmp
}