Создание списка установленных вручную пакетов и запросов отдельных пакетов

129

Я хотел бы получить список пакетов, установленных вручную apt или aptitude , и узнать, установлен ли пакет foobar вручную или автоматически. Есть ли какой-нибудь опрятный способ сделать это из командной строки?

    
задан Umang 16.08.2010 в 19:07
источник

11 ответов

145

Вы можете использовать любой из этих двух однострочных. Оба дают точный результат на моей машине и точнее, чем все предлагаемые до сих пор решения (6 июля 2014 г.) в этом вопросе.

Использование apt-mark :

comm -23 <(apt-mark showmanual | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)

Использование aptitude :

comm -23 <(aptitude search '~i !~M' -F '%p' | sed "s/ *$//" | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)

Очень мало пакетов по-прежнему попадают в трещины, хотя я подозреваю, что эти есть , фактически установленные пользователем, либо сразу после установки с помощью настройки локализации языка, либо, например, через установщик кодека Totem. Кроме того, похоже, что потоки заголовков linux также накапливаются, хотя я установил метапакет, не относящийся к версии. Примеры:

libreoffice-help-en-gb
openoffice.org-hyphenation
gstreamer0.10-fluendo-mp3
linux-headers-3.13.0-29    

Как это работает:

  1. Получить список установленных вручную пакетов. Для aptitude дополнительный sed удаляет оставшиеся пробелы в конце строки.
  2. Получить список пакетов, установленных сразу после новой установки.
  3. Сравните файлы, выводите только строки в файле 1, которые отсутствуют в файле 2.

Другие возможности не работают:

  • Используя файл ubuntu-14.04-desktop-amd64.manifest ( здесь для Ubuntu 14.04) вместо этого /var/log/installer/initial-status.gz . Больше пакетов отображается как установлено вручную, даже если это не так.
  • Использование apt-mark showauto вместо /var/log/installer/initial-status.gz . apt-mark , например, не включает пакет xserver-xorg, а другой файл -.

Я использовал разные записи StackExchange в качестве ссылок, однако ни одно из них не работает, как и выше:

Оба перечисляют больше пакетов, чем указанное решение.

EDIT: что делать, если вы обновили предыдущую версию:

Если вы обновили Ubuntu с одного выпуска до следующего, вам, вероятно, придется настроить этот процесс. В этом случае я проверил бы файл манифеста новой версии (см. Выше) в дополнение к файлу initial-status.gz из текущей версии. Вы можете легко сделать это, просто добавив другое сравнение. Использование только файла манифеста не будет работать, так как файл манифеста, к сожалению, не содержит всего, что делает файл initial_status.gz (я проверил).

    
ответ дан jmiserez 06.07.2014 в 17:01
источник
42

В более новых версиях пакета apt существует также команда apt-mark

apt-mark showmanual
    
ответ дан Daniel Alder 17.05.2012 в 18:21
18

apt-mark showauto | grep -iE '^foobar$' будет выводить «foobar», если пакет был установлен автоматически, ничего в противном случае.

aptitude search '!~M ~i' будет отображать пакеты, которые не были установлены автоматически. Очень жаль, что aptitude не будет частью установки по умолчанию на Ubuntu Desktop начиная с 10.10.

    
ответ дан Li Lo 16.08.2010 в 19:32
8

Следующий сценарий распечатает все пакеты, которые не установлены для автоматической установки, и, следовательно, были установлены вручную:

#!/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 печатает автоматически установленные пакеты.

    
ответ дан txwikinger 16.08.2010 в 21:42
6

Для 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.

    
ответ дан s1037989 04.02.2017 в 19:48
4

Как прокомментировали несколько человек, 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 предметов, которые, похоже, тоже не точны.

    
ответ дан cluelesscoder 27.10.2013 в 01:28
4

Чтобы получить список всех пакетов (не установленных, установленных пользователем или установленных по умолчанию для всех PPA), apt использует следующий метод:

apt list [option]

Возможные варианты, полезные для этого:

--installed , чтобы отображать только те пакеты, которые установлены в системе (из примерно 50 000 +)

--manual-installed , чтобы указать пакеты, которые были явно установлены командой, либо напрямую, либо как зависимости.

В качестве альтернативы вы можете сделать:

apt list --manual-installed | grep -F \[installed\] , чтобы получить список пакетов, которые были получены только из пользовательских команд и их зависимостей, и получить дополнительную информацию о них, например о поддерживаемой версии и архитектуре (x86, x86_64, amd64, all и т. д.)

    
ответ дан Aalok 07.02.2017 в 15:01
1

Как сказал Ли Ло, 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
  • Мы качаем, потому что можем.
ответ дан Oli 16.08.2010 в 19:41
1

Если никто не дает вам приятного ответа, используя команду apr-something, вы можете сделать это hard way . Apt-get сохраняет свою информацию в / var / lib / apt / extended_states. Любой файл, который установлен автоматически, будет добавлен в этот файл. Если вы установите пакет уже в этом файле вручную, пакет останется в этом файле, но с автоматической установкой: 0 во второй строке. Он не удаляется.

Примечание. Как и ожидалось, лучшие ответы, которые могут работать, если появились изменения в файлах. Я сохраняю мой на всякий случай, когда информация о местоположении файла полезна.

    
ответ дан Javier Rivera 16.08.2010 в 19:44
1

После многопользовательской игры мне удалось собрать этот скрипт. Это работает хорошо для меня:

# List of all packages currently installed
current=$(dpkg -l | awk '{print }' | 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/.* - (.*)//')
    date=$(date -r /var/lib/dpkg/info/$pack.list)

    echo "# $desc"
    echo "# $date"
    echo "sudo apt-get install $pack"
    echo -e ""
done
    
ответ дан dufferZafar 31.05.2015 в 22:28
-1

В этом списке будут указаны все установленные вручную пакеты: зависимости, удаленные пакеты, пакеты, установленные во время установки системы.

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.* " |
  sed -r "s/Commandline: apt-get//;s/ //" |
  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
}
    
ответ дан wieczorek1990 08.10.2014 в 15:39