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.


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

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

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}')

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!

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.