apt-get remove z usuniętym znakiem zastępczym znacznie więcej niż oczekiwano. czemu?


38

Ostatniej nocy próbowałem nagrać płyty CD. Rozzłościło mnie k3b i zamiast tego zdecydowałem się na brasero, więc postanowiłem usunąć k3b.

Wpisałem:

sudo apt-get remove k3b

Nacisnąłem klawisz Tab dwa razy i zobaczyłem, że mam zarówno dane k3b, jak i k3b w moim systemie. Zakładając, że nie potrzebowałbym danych k3b w moim systemie bez k3b, chciałem je również usunąć, więc wpisałem:

sudo apt-get remove k3b*

Niestety uderzyłem Y, żeby potwierdzić, nie patrząc. Odinstalował o wiele więcej niż k3bi k3b-data. Odinstalował pakiety, które nie pasowały do ​​mojego k3b*wyrażenia regularnego. Na przykład: transmissioni network-manager.

Jestem prawie pewna, że nie ma przestrzeni między k3bi *, ale nie wiem dlaczego jeszcze byłoby usunąć wszystko, co zrobił. Czy jest coś w apt-get, czego nie rozumiem?


Odpowiedzi:


38

Polecenie, które chcesz sudo apt-get remove '^k3b.*', ponieważ:

  • Musisz .*dopasować dowolną postać, dowolną liczbę razy
  • Musisz ^dopasować początek łańcucha
  • Musisz zacytować wyrażenie regularne, aby zapobiec interpretacji przez bash znaku *zastępczego

(Ta odpowiedź uzupełnia i podsumowuje poprzednie informacje dostarczone przez qbi i Flimm)


5
Jest to bezpieczne i można z niego korzystać, ale nie potrzebujesz .*. Możesz po prostu użyć sudo apt-get remove ^k3b. Obecność ^argumentu wystarcza, aby argument został zinterpretowany jako wyrażenie regularne, a gdy aptlub apt-getinterpretuje argument jako wyrażenie regularne, dopasowuje go w dowolnym miejscu w nazwie pakietu. Dlatego potrzebujesz ^- do zakotwiczenia dopasowania na początku nazwy pakietu. Wyrażenie regularne nie musi pasować do całej nazwy pakietu, tylko do dowolnej jego części.
— Eliah Kagan

1
@EliahKagan Thx, aby uzyskać dodatkowe informacje! (i rzeczywiście ma sens, że jeśli potrzebujesz ^, to nie potrzebujesz .*)
— Boris Dalstein,

30

Wyrażenie regularne *oznacza zero lub dowolnie wiele. Więc kazałeś apt-getusunąć wszystko, co zawiera, k3a następnie dowolną liczbę b, więc w zasadzie wszystko, co zawiera k3. Jeśli spróbuję wykonać polecenie w moim systemie, chce usunąć 58 pakietów.

sudo apt-get remove -s k3b*
Package k3b is not installed, so not removed
Package k3b-data is not installed, so not removed
Package k3b-dbg is not installed, so not removed
Package libcanberra-gtk3-0 is not installed, so not removed
Package libcanberra-gtk3-0-dbg is not installed, so not removed
Package libcanberra-gtk3-dev is not installed, so not removed
…
The following packages will be REMOVED:
  appmenu-gtk ardour audacity brasero brasero-cdrkit firefox-globalmenu
  gconf-editor gir1.2-appindicator-0.1 gnome-applets gnome-control-center
…
0 upgraded, 2 newly installed, 58 to remove and 0 not upgraded.

fuj! Utknąłem pracując nad tymi cholernymi maszynami do okien (gdzie * oznacza po prostu „i wszystko po”) o wiele za długo!
— Steve Goykovich

14
*Działa jako zamiennika dowolnego ciągu bash jak w DOS, ale niektóre polecenia podoba apt-getoczekiwać regex. Podczas pisania sudo apt-get remove -s k3b*, bash najpierw szuka plików w bieżącym katalogu, które zaczynają się od k3b. Jeśli znajdzie jakiś, zastąpi ten argument tymi nazwami plików. Jeśli nie, przejdzie k3b*bezpośrednio do apt-get, co zinterpretuje to jako wyrażenie regularne. Jeśli nie chcesz, aby bash zinterpretował gwiazdkę jako symbol wieloznaczny jako pierwszy (czego prawdopodobnie nie masz), otoczyć argument pojedynczymi cudzysłowami, jak poniżej:sudo apt-get remove -s 'k3b*'
— Flimm 12.12. O

3
Tak byłoby zamierzone polecenie sudo apt-get remove -s 'k3b.*'. Natknąłem się na tę odpowiedź i uważam, że to naprawdę ważne, aby wiedzieć. IMHO jest to dość nieoczekiwane i naznaczyłbym to jako błąd „nieoczekiwanego zachowania” apt-get ... zwykle oczekujesz znaczenia „glob”, a nie „regexp”, jeśli nie zostanie określone. W każdym razie dzięki i +1!
— Rmano,

1
A dla takich jak ja, którzy nie wiedzieli: ta -sopcja oznacza „symulację”. Mówi, apt-getaby nie wykonywać operacji, ale po prostu informować o tym, co by się stało bez -sopcji.
— Boris Dalstein,

Myślę, że użycie pojedynczych cudzysłowów do tworzenia globowania NIE działa, przynajmniej w marionetce. I to jest nieoczekiwane. W programie „znajdź”, jeśli napiszę projekt find / -iname * *, znajdę wszystko, co zaczyna się od projektu, a nie coś, co zawiera „projekt” i wszystko po nim. Jako dowód dotyczący marionetki zauważ, jak moje wyniki mówią „regex”, a wyniki to potwierdzają?
— Dennis

9

Użyj sudo apt-get remove ^k3bzamiast tego. Podczas instalowania lub usuwania pakietów *jest często niebezpieczny i rzadko potrzebny. Jeśli używasz *, powinieneś go zacytować, ale to nie czyni go bezpieczniejszym, ponieważ jego tendencja do wybierania znacznie większej liczby pakietów, niż zamierzasz, jest wynikiem sposobu apti apt-getinterpretacji, a nie efektem rozwijania nazwy ścieżki .

  • Nawet bezpieczne zastosowania* są często niepotrzebne .
  • Niebezpieczne zastosowania są brutalne . Usunięcie k3b*usuwa każdy pakiet, który zawiera k3 dowolne miejsce w jego nazwie (i każdy pakiet, który zależy od takiego pakietu). To nie jest literówka - zawieranie k3jest wystarczające, nawet bez b, ponieważ b*oznacza „zero lub więcej bs”.

Po uruchomieniu aptlub apt-getz install, removelub purgedziałania, każdy kolejny argument to pierwszy 1 interpretowane jako nazwa opakowaniu jednostkowym. Jeśli istnieje pakiet o tej dokładnej nazwie, wykonywana jest dla niego akcja.

Jeśli nie ma takiego pakietu, apti apt-getsprawdzi, czy argument zawiera którekolwiek z typowych wyrażeń regularnych metaznaki 2 . , ?, +,* , |, \[, ^, lub$ . Jeśli nie, to gotowe - nie znaleziono pakietu.

Jeśli nie zawierają żadnego z tych znaków, to jest traktowane jako wyrażenie regularne i porównywana z jakiejkolwiek części jakiejkolwiek nazwy pakietu. Nie musi pasować do całej nazwy. Jak powiedzieli inni, *wyrażenie regularne nie oznacza tego samego, co *glob. ?też nie. W wyrażeniu regularnym:

  • *pozwala, aby poprzedni element pojawiał się dowolną liczbę razy - w tym tylko raz lub wcale - zamiast dokładnie raz.
  • ?sprawia, że ​​poprzedni element jest opcjonalny - to znaczy, że może pojawić się zero lub jeden raz.

apt-get (8) ( man apt-get) mówi:

Jeśli żaden pakiet nie pasuje do podanego wyrażenia, a wyrażenie zawiera jedno z „.”, „?” lub „*”, wówczas przyjmuje się, że jest to wyrażenie regularne POSIX i jest stosowane do wszystkich nazw pakietów w bazie danych. Wszelkie dopasowania są następnie instalowane (lub usuwane). Zauważ, że dopasowanie odbywa się przez podciąg, więc „lo. *” Dopasowuje „how-lo” i „najniższą”. Jeśli jest to niepożądane, zakotwicz wyrażenie regularne znakiem „^” lub „$” albo utwórz bardziej szczegółowe wyrażenie regularne.

Manpage tylko wspomina ., ?i *, ale jest niekompletna , jak +, |, [, ^, i $są również wystarczające, aby pozwolić apt-getlub aptzinterpretować jako wzorzec wyrażenia regularnego. 3)

Chociaż można dopasować dowolną ilość dowolnych znaków z .*- nie wystarczy *tylko --you to potrzebne, jeśli wydaje się w środku swojego wyrażenia regularnego. Ponieważ wzorzec jest dopasowywany do dowolnego podciągu nazwy pakietu, nie ma sensu na końcu (lub początku) wzorca.

Strona wspomina ^i$ . Tych (szczególnie ^) są kluczem do pisania bezpiecznych, skutecznych wzorców do użytku z install, removelub purgedziałania w aptlub apt-get.

  • ^zakotwicza wyrażenie regularne na początku całego łańcucha. ^k3bwybiera wszystkie pakiety, których nazwy zaczynają się k3b.
  • $zakotwicza wyrażenie regularne na końcu całego łańcucha. k3b$wybrałby wszystkie pakiety, których nazwy kończą się na k3b.

Dlatego możesz użyć tego polecenia, aby bezpiecznie usunąć pakiety:

sudo apt-get remove ^k3b

Wreszcie, w konkretnym przypadku, o którym wspomniałeś, równie dobrze możesz po prostu podać oba nazwiska:

sudo apt-get remove k3b k3b-data

Wtedy unikniesz całej tej złożoności! (Chociaż zakotwiczenie za pomocą ^jest proste, gdy już się do tego przyzwyczaisz). Lub użyj rozszerzenia nawiasów , które twoja powłoka rozwija do powyższego polecenia:

sudo apt-get remove k3b{,-data}

1 Istnieją dwa wyjątki to: (a) niektóre opcje (np -f, --purge) są rozpoznawane i (b) niektóre znaki interpunkcyjne pojawiające się na końcu argumentu, które byłyby uznawane za nazwę pakietu wykonywać działania mogą być służy do zmiany tego, co zostało zrobione (np. sudo apt install ubuntu-desktop^instaluje zadanie zamiast pakietu i kiedy ^pojawia się na końcu).

2 Istnieją inne metaznaki wyrażeń regularnych. Na przykład \jest obsługiwany przez wszystkie dialekty wyrażeń regularnych i powszechnie używane. ., ?, +, *, |, [, ^, I $po prostu stało się metaznaki apt deweloperzy zdecydowali spowodowałaby interpretację jako wyrażenie regularne (po ustąpieniu jako dokładnym pakiecie o nazwie nie udało).

3 Najłatwiejszym sposobem sprawdzenia tego jest symulacja instalacji lub usunięcia z takim wzorcem, przy użyciu -sopcji opisanej powyżej. Na przykład uruchamianie apt -s install ^virtualboxprogramów, sudo apt install ^virtualboxktóre skutkowałyby próbą zainstalowania każdego pakietu, o którym menedżer pakietów wie, od którego imienia zaczyna się nazwa virtualbox. To zachowanie można jednak również zweryfikować, sprawdzając kod źródłowy . Sprawdź CacheSetHelper::PackageFromRegExfunkcję w cacheset.cc.


1

Prawdopodobnie usuniesz bibliotekę zawierającą k3b, od której zależały te programy.

Krótko mówiąc, możesz nigdy nie wiedzieć. Odradzam używanie symboli wieloznacznych do usuwania rzeczy i czytania ich po wyświetleniu monitu (przepraszam).

Również bez opcji -n wyrażenia regularne używają wszystkich pól, a nie tylko nazw

http://ccrma.stanford.edu/planetccrma/man/man8/apt-cache.8.html

również qbi jest poprawne, twoje wyrażenie regularne jest wadliwe od samego początku


Jeszcze jedno, w przypadkach takich jak twoje (dane k3b i k3b) po prostu apt-get odinstaluj k3b. Apt poinformuje Cię wtedy, jeśli masz zainstalowane rzeczy, których już nie potrzebujesz, i co musisz zrobić, aby je usunąć.
— coteyr

łał! Nigdy bym się nie spodziewał, że przeszuka także opisy! tak, to zdecydowanie coś, czego nigdy więcej nie zrobię! (i będę
— musiał

Link jest zepsuty, czy mógłbyś wyjaśnić, jak używać -n?
— Seanny123 17.09.13

-n oznacza wyszukiwanie tylko w polu nazw.
— coteyr

Po próbie opcja -n nie jest rozpoznawana przez apt-get remove, tylko przez apt-get cache. Wygląda na to, że tak naprawdę apt-get removeszuka tylko nazw pakietów, a nie opisów.
— Boris Dalstein,
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.