Zignoruj ​​pakiety, które nie są obecnie instalowane przy użyciu „apt-get remove”

15

Mam scenariusz, w którym chciałbym usunąć zestaw pakietów, które mogą lub nie mogą być zainstalowane, i chciałbym, aby apt-get usunął te, które są, i po cichu zignorował te, które nie są. Coś jak:

apt-get remove foo bar baz

który, gdyby zainstalowano foo i bar, ale nie był baz, usunie foo i bar bez narzekań na baz. Czy jest na to sposób?

Rzeczy, które próbowałem, ale nie działały, z cup-dbg jako moim faktycznie zainstalowanym pakietem kozła ofiarnego do usunięcia:

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

Wiem, że mógłbym to zrobić za pomocą skryptu powłoki i odrobiny dpkg --listmagii, ale chciałbym uniknąć złożoności, która nie jest absolutnie konieczna.

javawizard
źródło
Ta odpowiedź w końcu zadziałała dla mnie . Głupia naprawa głupiego problemu. Pamiętaj, że w rzeczywistości Launchpad ma wadę, więc nie krępuj się.
Jeff

Odpowiedzi:

8

Czy powrót do narzędzia niższego poziomu, takiego jak dpkg, jest opcją?

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 ...

Aby usunąć pliki konfiguracyjne pakietów, użyj purge jak poniżej

dpkg --purge foo bar libperl-dev
barti_ddu
źródło
1
Powinienem wspomnieć, że pakiety, które mają zostać usunięte, mogą mieć odwrotne zależności, i chciałbym, aby te również zostały usunięte. Apt-get jest zatem znacznie lepszy niż dpkg, ale zaakceptuję twoją odpowiedź, ponieważ wydaje się, że nie ma naprawdę lepszego sposobu na zrobienie tego.
javawizard
7

Używam apt-get remove --purge(aka apt-get purge) dla zależności następującej po liście pakietów. Aby obsłużyć pakiety, które nie istnieją, odfiltrowuję pakiety, które nie są zainstalowane za pomocą następującego skryptu.

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
Lucas
źródło
3

W przypadku Debiana ≤ 9 możliwe jest użycie aptitudezamiast apt-get:

sudo aptitude remove -y cups-dbg bogus-package

Aptitude drukuje ostrzeżenia, ale mimo to usuwa pakiety:

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

Jeśli chcesz wyczyścić (usunąć pliki konfiguracyjne pakietu) zamiast usunąć (zachować pliki konfiguracyjne), pamiętaj, że aptitudeusuwa tylko podane bezpośrednio pakiety, a nieużywane zależności są tylko usuwane. Możesz jednak wyczyścić wszystkie usunięte pakiety w drugim kroku:

apt-get -y purge $(dpkg -l | grep ^rc | awk '{print $2}')
vog
źródło
dobrze. czasami po bogus-packageprostu miał złe imię. tak więc, gdybyśmy mieli 500 pakietów, lepiej byłoby też przeanalizować fałszywe pakiety i wykonać kilka sztuczek (na przykład liczby za brakującą nazwą itp.). Czy możesz udzielić wskazówek, jak to zrobić? ..
nyxee
@nyxee Proponuję zadać to jako nowe pytanie, wskazując dokładnie, co chcesz osiągnąć.
vog
1
Byłoby to miłe obejście, z wyjątkiem 1) aptitude nie jest już domyślnie instalowany na Ubuntu 18.04 i 2) aptitude ma całkiem inny (można powiedzieć, dziwny) sposób obsługi symboli wieloznacznych.
Jeff
To nie działa dla mnie na Debianie 10. Rozumiem,Couldn't find any package whose name or description matched 'QUX' Unable to apply some actions, aborting
pdoherty926,
@ pdoherty926 Dzięki za podpowiedź. Zweryfikowałem to i odpowiednio dostosowałem swoją odpowiedź.
vog
0

Kolejny mały 2-liniowy, jeśli ktoś potrzebuje użycia 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
}

Wyjaśnienie:

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!
Meir
źródło
Witamy w SuperUser! Czy do swojej odpowiedzi dodałbyś więcej opisu tego, co robi skrypt i jak to robi?
El8dN8
@ El8dN8 Dodano wyjaśnienie
Meir