Створення списку встановлених вручну пакетів та запитів окремих пакетів


183

Я хотів би отримати список пакунків, встановлених вручну aptабо, aptitudeі мати змогу дізнатися, чи встановлено foobarпакет вручну чи автоматично. Чи є якийсь акуратний спосіб зробити це з командного рядка?


Дивіться цю відповідь на unix.stackexchange.com щодо рішення, яке фільтрує пакети акцій.
Дірк Бергстром

Можливий дублікат? - askubuntu.com/questions/365
jrg


Дійсно гарне рішення, що виключає встановлені за замовчуванням пакети: Ubuntu список явно встановлених пакетів
pcworld

Будьте уважні до коментарів відповідей тут. Люди не кажуть, як з’являється більше пакетів, але вони забувають, що існують пакунки залежностей, встановлені з встановленого вручну.
Andre Figueiredo

Відповіді:


206

Ви можете використовувати будь-який з цих двох одноводкових. Обидва отримують абсолютно однаковий вихід на моїй машині і є більш точними, ніж усі рішення, запропоновані до цього часу (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)

Далеко не всі пакети ще падають через тріщину, хоча я підозрюю , що вони є на самому справі встановлено користувачем, або відразу після установки через настройку локалізації мови або , наприклад , з допомогою програми установки Тотема кодека. Крім того, начебто накопичуються версії linux-header, навіть якщо я встановив лише мета-пакет, який не залежить від версії. Приклади:

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

Як це працює:

  1. Отримайте список встановлених вручну пакетів. Для здатності додаткові 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 з поточного випуску. Ви можете легко зробити це, додавши ще одне порівняння. Використання просто файлу маніфесту не буде працювати, так як файл маніфесту, на жаль, не містить всього, що робить файл Initi_status.gz (я перевірив).


7
Це не спрацювало для мене, оскільки /var/log/installer/initial-status.gzйого немає. Також я хочу знати, чи це залежить від маркування вправ manualчи ні?
Анвар

1
На жаль, для серверних версій немає маніфесту.
Антті Хаапала

Я запустив showmanualкоманду (нижче). І використовуйте commдля порівняння двох (відсортованих) списків. showmanualРезультат дав мені 1840 більш унікальні пакети з apt-mark showmanualяких немає цього методу. Ніякі пакети не були унікальними для виходу цього команди comm. Думаю, цікавіше зафіксувати, що для мого ПК в обох результатах вказано 894 пакети. Не впевнений, чому існує така велика невідповідність. Деякі (багато?) Пакети здаються специфічними для випуску. Такі оновлення, як XOrg, GTK, компоненти та інші lib*речі можуть бути оновленнями. У будь-якому випадку ця відповідь - це дуже вдалий початок.
буде

Я просто порівняв ваші рішення з apt-mark showmanual. Цікаво, скільки різниць видно. у вашому списку 238 пакунків, а показові повертають 1717 пакунків. З 2179 встановлених пакетів лише 223 в обох списках, 15 - лише у вашому (приклади: nodejs, lightdm), а 223 - лише у показовому (приклади: xserver-xorg, ubuntu-desktop). Схоже, ваш список корисніший, але не знаючи, звідки беруться ці відмінності, вирішити непросто ... (але я впевнений, що встановив nginx та lightdm вручну ...) [Вибачте, що я щойно написав те саме;)]
Даніель Алдер

64

У новіших версіях пакета apt також є команда apt-mark

apt-mark showmanual

35
Це показує набагато більше пакетів, ніж я встановив вручну.
Умань

1
@Umang Ви маєте рацію. Я б сказав, що це було не так, коли я писав цю відповідь. У моїй системі немає жодних причин вважати linux-image-3.11.0-*-genericтощо як посібник
Даніель Алдер

1
@Umang, можливо, це допоможе вам askubuntu.com/questions/432743/… , але відповідь не приймається. Справа в тому, що багато пакунків із свіжої установки вже позначені як ручна. Але є ще якісь дивні речі. Залишатися на моєму прикладі: linux-image-3.13.0-24-genericє ручним, але струм linux-image-3.13.0-27-generic- автоматичним. Здається, що при оновленні референтного пакету (в даному випадку linux-image-generic, який змінив залежності), ручне позначення встановлюється автоматично
Даніель Альдер

5
@DanielAlder деякі пакети свіжої установки мають бути позначені як посібники. Якщо жоден пакет не позначений як ручний, всю систему можна видалити за допомогою apt-get autoremove. Це точно не те, що ти хочеш.
Антон К

2
Якщо "встановлений вручну" означає "встановлений користувачем після початкової установки ОС", це не є правильною відповіддю.
Seamus

21

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


1
З усіх відповідей протягом багатьох років, це єдиний, який навіть наближається до сервера 18.04.
Квентін Скусен

20

apt-mark showauto | grep -iE '^foobar$' виведе "foobar", якщо пакет був встановлений автоматично, нічого іншого.

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


aptitude searchпоказує ВСІ пакети, а не лише ті, які встановлюються вручну (я припускаю, що цього хотіла ОП)
Oli

1
@Oli: вивчіть схеми пошуку можливостей; шаблон, який я там використовую, повинен робити саме те, що хоче ОП.
Лі Ло

Я його запустив . Він показує ціле завантаження пакетів, які не встановлені.
Олі

7
Щось із цим неправильно, я використовую, aptitude search '!~M ~i'і в ньому перераховано 1043 пакунки. Я не можу встановити стільки пакетів вручну.
ThatGraemeGuy

Це, безумовно, не працює як потрібно, друкує попередньо встановлені пакети.
Ірфій

9

Наступний скрипт роздрукує всі пакунки, які не встановлені на автоматичну установку і, отже, були встановлені вручну:

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


Кудо вам добре, пане. Це насправді працює, на відміну від прийнятої відповіді.
Ірфій

покажіть лише пару пакунків для мене --- безумовно, багато з них не вистачає.
Рмано

Те саме тут, безумовно, відсутні пакети, встановлені вручну, одразу після того, як я їх встановив.
Девід Люнг Медісон

Використання sys.exit(1)без цього import sysможе призвести до помилки в нових версіях python. Або import sysвикористовуйте exit(1).
Videonauth

7

Для отримання списку всіх пакетів (не встановлених, встановлених користувачем або встановлених за замовчуванням у всіх ППА) aptвикористовується наступний метод:

apt list [option]

Можливі варіанти, корисні для цього:

--installed відображати лише ті пакунки, які встановлені в системі (з приблизно 50 000+)

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

Можна також зробити:

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


5

Як коментують декілька людей, здається, що влучний шоумендул трохи баггі (і я повідомив про це як помилку 727799 ). Коли я його використовую, він фактично повідомляє про багато речей, які навіть не увійшли в систему / var / lib / apt / extension_states (де це має бути збережено), а apt-get не реєструє речі як встановлені в / var / lib / apt / extension_states (просто в / var / lib / dpkg / status). Скрипт python txwikinger вище малює безпосередньо з / var / lib / apt / extension_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 предметів, який теж не здається точним.


1
Використання sys.exit(1)без цього import sysможе призвести до помилки в нових версіях python. Або import sysвикористовуйте exit(1).
Videonauth

4

Я хотів би дати рішення GUI.

введіть тут опис зображення

  1. відчинено Synaptic Package Manager

  2. Йти до Status

  3. Клацніть Installed (manual)

Він надасть список пакунків, встановлених вручну за apt або aptitude.

На жаль, я не зміг знайти жодного варіанту, Custom Filtersщоб дізнатися, чи встановлено foobarпакет вручну чи автоматично.

Якщо пакет знаходиться під, Installedале не знаходиться під Installed (manual)ним, він був встановлений автоматично. Якщо пакет знаходиться нижче, Installed (manual)він був встановлений вручну.


2

Якщо ніхто не дає вам гарної відповіді, використовуючи команду apr-something, ви можете зробити це важким способом . Apt-get зберігає свою інформацію в / var / lib / apt / extension_states. Будь-який файл, встановлений автоматично, буде доданий до цього файлу. Якщо ви встановите пакет уже в цьому файлі вручну, він залишиться у цьому файлі, але з автоматичним встановленням: 0 у другому рядку. Це не видалено.

Примітка. Як очікується, краще відповіді, які, ймовірно, спрацюють, якщо з’являться зміни розміщення файлів. Я зберігаю свою на випадок, якщо інформація про розташування файлу буде корисною.


1
Ні. Я швидко переглянув цей файл, щоб виявити, що liferea позначений як встановлений автоматично. Я зробив це, apt-get install lifereaі він не встановився, але я отримав висновок, який був таким чином, що "позначено як встановлено вручну". Тепер liferea все ще є у файлі, за винятком наступного рядка 0замість 1. Крім того, ви повинні змінити свою схему регулярного вираження " foobar$"замість просто foobar.
Умань

Це правда. Моя вина, у моїй системі немає рядка з 0, але це має бути рідкісним випадком. Відповідь я оновлюю про всяк випадок.
Хав'єр Рівера

2

Після багатого гуглінгу я встиг зібрати цей сценарій. Це добре для мене:

# 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

Ви можете використовувати sort -uзамість цього sort | unique. Оскільки apt-markархітектура не відображається, вам слід зняти її з виводу dpkg перед встановленими операціями (або використовувати dpkg-query -W -f='${Package}\n'). Крім того, dpkg може перелічити деякі пакунки, які не встановлені на даний момент. Що стосується "desc", ви можете використовувати `dpkg-query -W -f = '# $ {binary: Summary} \ n' $ pack, який швидше.
jarno

О, apt-markможе відображатися архітектура для деяких пакетів, але не для багатьох dpkg -l.
jarno

apt-cache searchповільно. Отримати заздалегідь список встановлених дат, використовуючи щось на зразок help.ubuntu.com/community/ListInstalledPackagesByDate, можливо, буде більш ефективним
оптимічний

1

Як сказав Лі Ло, вам apt-mark showautoслід автоматично встановити жирний список речей.

Тепер, щоб показати речі, які встановлюються вручну, виявляється, є чудовий простий модифікатор пошуку на здатність. Але ти не хочеш цього робити. Ви хочете написати величезну команду 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
  • Ми розкочуємось, бо можемо.

Я сумніваюся, що це точно, оскільки dpkg часто показує пакунки, які не встановлені
txwikinger

Я знаю, що ти маєш на увазі, але мій баш-фу недостатньо сильний. Я знаю, що ви можете показати статус за допомогою dpkg-запиту, зніміть його, а потім відріжте його. Я поїду.
Олі

comm -3 <(dpkg -l | grep '^ii' | cut -d \ -f 3|sort) <(apt-mark showauto|sort)належним чином краще;)
LassePoulsen

-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.* $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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.