Игнорировать пакеты, которые в данный момент не установлены, при использовании «apt-get remove»

15

У меня есть сценарий, в котором я хотел бы удалить набор пакетов, которые могут или не могут быть установлены, и я хотел бы, чтобы apt-get удалил те, которые есть, и молча проигнорировал те, которые не были. Что-то вроде:

apt-get remove foo bar baz

который, если бы foo и bar были установлены, но baz не был установлен, удалил бы foo и bar без жалоб на baz. Есть ли способ сделать это?

Вещи, которые я пробовал, которые не работали, с cups-dbg в качестве фактически установленного пакета моего козла отпущения:

jcp@a-boyd:~$ sudo apt-get remove -y cups-dbg bogus-package
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package bogus-package

jcp@a-boyd:~$ sudo apt-get remove --ignore-missing cups-dbg bogus-package
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package bogus-package

jcp@a-boyd:~$ sudo apt-get remove --fix-broken cups-dbg bogus-package
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package bogus-package

Я знаю, что мог бы сделать это с помощью сценария оболочки и некоторой dpkg --listмагии, но я хотел бы избежать любой сложности, которая не является абсолютно необходимой.

javawizard
источник
Этот ответ сработал для меня в конце концов. Тупое решение для глупой проблемы. Обратите внимание, что на Launchpad есть дефект, так что не стесняйтесь.
Джефф

Ответы:

8

Является ли вариант возврата к инструменту более низкого уровня, такому как dpkg ?

dpkg --remove foo bar libperl-dev
dpkg: warning: ignoring request to remove foo which isn't installed
dpkg: warning: ignoring request to remove bar which isn't installed
(Reading database ... 169132 files and directories currently installed.)
Removing libperl-dev ...

Для удаления пакетов конфигурационных файлов используйте purge, как показано ниже

dpkg --purge foo bar libperl-dev
barti_ddu
источник
1
Я должен был упомянуть, что пакеты, которые будут удалены, могут иметь обратные зависимости, и я бы хотел, чтобы те тоже были удалены. Поэтому Apt-get намного лучше, чем dpkg, но я приму ваш ответ, так как кажется, что на самом деле нет лучшего способа сделать это.
javawizard
7

Я использую apt-get remove --purge(ака apt-get purge) для следующей зависимости со списком пакетов. Для обработки пакетов, которые не существуют, я отфильтровываю пакеты, которые не установлены с помощью следующего сценария.

pkgToRemoveListFull="cups-dbg bogus-package"
pkgToRemoveList=""
for pkgToRemove in $(echo $pkgToRemoveListFull); do
  $(dpkg --status $pkgToRemove &> /dev/null)
  if [[ $? -eq 0 ]]; then
    pkgToRemoveList="$pkgToRemoveList $pkgToRemove"
  fi
done
apt-get --yes --purge remove $pkgToRemoveList
Лукас
источник
3

Для Debian ≤ 9 можно просто использовать aptitudeвместо apt-get:

sudo aptitude remove -y cups-dbg bogus-package

Aptitude выводит предупреждения, но тем не менее продолжает удалять ваши пакеты:

Couldn't find any package whose name or description matched "bogus-package"
...
Removing cups-dbg ...
...

Если вы хотите очистить (удалить файлы конфигурации пакета), а не удалить (сохранить файлы конфигурации), обратите внимание, что aptitudeудаляются только те пакеты, которые были предоставлены напрямую, а неиспользуемые зависимости удаляются. Однако вы можете удалить все удаленные пакеты на втором этапе:

apt-get -y purge $(dpkg -l | grep ^rc | awk '{print $2}')
ВОГ
источник
Ok. иногда, bogus-packageпросто было неправильное имя. так что, если у нас было около 500 пакетов, было бы лучше проанализировать фиктивные пакеты и сделать некоторые трюки (например, числа после имени нехватки и т. д.), поэтому, можете ли вы дать несколько советов о том, как это сделать? ..
nyxee
@nyxee Предлагаю задать этот вопрос как новый вопрос, точно указав, чего вы хотите достичь.
ВОГ
1
Это был бы хороший обходной путь, за исключением 1) aptitude больше не устанавливается по умолчанию в Ubuntu 18.04 и 2) aptitude имеет довольно другой (можно сказать странный) способ обработки подстановочных знаков.
Джефф
Это не работает для меня в Debian 10. Я вижу,Couldn't find any package whose name or description matched 'QUX' Unable to apply some actions, aborting
pdoherty926
@ pdoherty926 Спасибо за подсказку. Я подтвердил это и скорректировал свой ответ соответственно.
ВОГ
0

Еще один маленький 2-х слойный, если кому-то нужно использовать apt:

purge_packages () {
  matchedPackages="$(echo "$(apt list --installed $* 2>/dev/null)" | grep -v '^Listing\.\.\.' | sed -s 's|[/ ].*||' | tr '\n' ' ' | sed 's/ *$//;s/^ *//')"
  [[ -n "$matchedPackages" ]] && apt purge -yq $matchedPackages
}

Explination:

apt list --installed $*         # Lists packages matched from function args, the --installed flag limits results to installed packages

2>/dev/null                     # Disregard the warning about using this command in a script

grep -v '^Listing\.\.\.'        # Remove the first line of output that says "Listing..." or "Listing... Done"

sed -s 's|[/ ].*||'             # Remove the rest of the line after the package name (I'm checking for / or space though it looks like just the slash is needed but package names will never have a space)

tr '\n' ' '                     # Put it all on one line separated by spaces

sed 's/ *$//;s/^ *//'           # Remove trailing and leading spaces from the line so it will be blank during the test next line if nothing was matched

[[ -n "$matchedPackages" ]]     # Check if any packages were matched

apt purge -yq $matchedPackages  # Purge them!
Меир
источник
Добро пожаловать в SuperUser! Вы бы добавили больше описания к своему ответу относительно того, что делает ваш скрипт и как он это делает?
El8dN8
@ El8dN8 Добавлено объяснение
Меир