apt-get remove с удаленными подстановочными знаками намного больше, чем ожидалось. Зачем?
Прошлой ночью я пытался записать компакт-диски. Раздражая k3b и выбрав вместо этого brasero, я решил удалить k3b. Я набрал:
sudo apt-get remove k3b
Я дважды нажал на tab и увидел, что в моей системе есть как k3b, так и k3b-данные. Предполагая, что мне не нужны данные k3b в моей системе без k3b, я тоже хотел их удалить, поэтому набрал:
sudo apt-get remove k3b*
К сожалению, я нажал Y, чтобы подтвердить, не глядя. Он удалил намного больше, чем k3b и k3b-data. Он удалил пакеты, которые не подходили для моего регулярного выражения "k3b*". Например: передача и сетевой менеджер
Я вполне уверен, что у меня не было пробела между k3b и *, но я не знаю, почему иначе он удалил бы все, что сделал. Есть ли что-то в apt-get, что я неправильно понимаю?
4 ответа
Команда, которую вы хотите sudo apt-get remove '^k3b.*', так как:
- Тебе нужно
.*соответствовать любому символу, любое количество раз - Тебе нужно
^чтобы соответствовать началу строки - Вы должны процитировать регулярное выражение для предотвращения интерпретации bash
*в качестве символа подстановки
(Этот ответ завершает и суммирует предыдущую информацию, предоставленную qbi и Flimm)
Регулярное выражение * обозначает ноль или произвольно много. Так вы сказали apt-get удалить все, что содержит k3 с последующим любым количеством bтак что в основном все, что содержит k3, Если я попробую вашу команду в моей системе, она захочет удалить 58 пакетов.
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.
использование sudo apt-get remove ^k3b вместо. Когда вы устанавливаете или удаляете пакеты, * часто опасен и редко нужен. Если вы используете * Вы должны заключить его в кавычки, но это не делает его более безопасным, потому что его тенденция выбирать гораздо больше пакетов, чем вы предполагаете, является результатом способа apt а также apt-get интерпретировать это, а не эффект расширения пути.
- Даже безопасное использование
*часто не нужны. - Небезопасное использование жестоко. Удаление
k3b*удаляет каждый пакет, который содержитk3где-нибудь в его имени (и каждый пакет, который зависит от такого пакета). Это не опечатка, содержащаяk3достаточно даже безb, так какb*означает "ноль или болееbs ".
Когда ты бежишь aptили же apt-get с install, remove, или же purge действие, каждый последующий аргумент сначала интерпретируется как имя отдельного пакета. Если пакет с таким точным именем существует, для него выполняется действие.
Если такой упаковки нет, apt а также apt-get проверит, содержит ли аргумент какой-либо из общих метасимволов регулярного выражения 2 ., ?, + , *, |, \[, ^ , или же $, Если нет, то сделано - пакет не найден.
Если он содержит какой-либо из этих символов, он обрабатывается как регулярное выражение и сопоставляется с любой частью любого имени пакета. Это не должно соответствовать целому имени. Как уже говорили другие, * в регулярном выражении не означает то же самое, что * в шар. ? тоже нет В регулярном выражении:
*позволяет предыдущему элементу появляться любое количество раз - включая только один раз или вообще не появляться - вместо ровно одного раза.?делает предыдущий элемент необязательным - то есть, он позволяет ему появляться ноль или один раз.
apt-get (8) (man apt-get) говорит:
Если ни один пакет не соответствует данному выражению, и выражение содержит один из '.', '?' или '*', тогда предполагается, что это регулярное выражение POSIX, и оно применяется ко всем именам пакетов в базе данных. Любые совпадения затем устанавливаются (или удаляются). Обратите внимание, что сопоставление выполняется с помощью подстроки, поэтому 'lo.*' Соответствует 'how-lo' и 'наименьшему' Если это нежелательно, закрепите регулярное выражение символом "^" или "$" или создайте более конкретное регулярное выражение.
Справочная страница только упоминает ., ?, а также *, но оно неполное, так как +, |, [, ^, а также $ также достаточно, чтобы позволить apt-get или же apt интерпретировать шаблон как регулярное выражение. 3
Хотя вы можете сопоставить любое количество любых символов с .* - не только * - вам нужно только это, если оно появится в середине вашего регулярного выражения. Поскольку шаблон сопоставляется с любой подстрокой имени пакета, он не имеет смысла в конце (или начале) шаблона.
Руководство упоминает ^ а также $, Эти (особенно ^) являются ключом к написанию безопасных, эффективных шаблонов для использования с install, remove, или же purge действия в apt или же apt-get,
^привязывает регулярное выражение к началу всей строки.^k3bвыбирает все пакеты, имена которых начинаются сk3b,$привязывает регулярное выражение к концу всей строки.k3b$выбрал бы все пакеты, имена которых заканчиваются наk3b,
Поэтому вы можете использовать эту команду для безопасного удаления пакетов:
sudo apt-get remove ^k3b
Наконец, в конкретном случае, который вы упомянули, вы могли бы просто передать оба имени самостоятельно:
sudo apt-get remove k3b k3b-data
Тогда вы избежите всей этой сложности! (Хотя якорь с ^ Это просто, если вы привыкли к нему.) Или используйте расширение скобки, которое ваша оболочка раскрывает в приведенную выше команду:
sudo apt-get remove k3b{,-data}
1 Есть два исключения из этого: (а) некоторые варианты (например, -f , --purge ) распознаются, и (b) некоторые знаки препинания, появляющиеся в конце аргумента, который в противном случае был бы принят в качестве имени пакета для выполнения действия, могут использоваться для изменения того, что сделано (например, sudo apt install ubuntu-desktop^ устанавливает задачу, а не пакет, и когда ^ появляется в конце).
2 Существуют и другие метасимволы регулярных выражений. Например, \ поддерживается всеми диалектами регулярных выражений и широко используется. . , ? , + , * , | , [ , ^ , а также $ просто метасимволы, которые разработчики APT решили вызвать интерпретацию как регулярное выражение (после разрешения, когда точный названный пакет потерпел неудачу).
3 Самый простой способ убедиться в этом - смоделировать установку или удаление по такой схеме, используя -s вариант как описано выше. Например, бег apt -s install ^virtualbox показывает, что sudo apt install ^virtualbox будет иметь эффект попытки установить каждый пакет, о котором знает менеджер пакетов, чье имя начинается с virtualbox , Однако такое поведение также можно проверить, изучив исходный код. Проверить CacheSetHelper::PackageFromRegEx функция в cacheset.cc ,
Скорее всего, вы удалите библиотеку с k3b, от которой зависели эти программы.
Короче говоря, вы никогда не узнаете. Я рекомендую не использовать подстановочный знак, чтобы удалить что-либо и прочитать что-либо по запросу (извините).
Кроме того, при поиске без регулярного выражения -n используются все поля, а не только имена.
http://ccrma.stanford.edu/planetccrma/man/man8/apt-cache.8.html
также Qbi правильно, ваше регулярное выражение имеет недостатки с самого начала
Ты можешь использовать
apt searchкоторый имеет преимущество поиска как в именах пакетов, так и в описаниях пакетов, но это также немного опасно. например, если вы хотите удалить любой пакет, связанный с
MY_PATTERN Вы можете запустить:
sudo apt search MY_PATTERN | grep "^[^\ ]*/" -o | sed 's/\///' | xargs -I '{}' sudo apt remove -y '{}'
БУДЬТЕ ОСТОРОЖНЫ: не используйте небольшие поисковые шаблоны, которые можно найти во многих словах, например
he, and,.... это может привести к удалению несвязанного пакета и, следовательно, к повреждению. Перед запуском проверьте вывод
apt search MY_PATTERN первый.
apt search MY_PATTERN: Найдите шаблон в именах пакетов и описаниях пакетов в удаленных репозиториях.
grep "^[^\ ]*/" -o: извлечь имя пакета.
sed 's/\///': удалять
/ из извлеченных имен.
xargs -I '{}' sudo apt remove -y '{}': удалить по одному.
Используйте.* Вместо * и заключите в кавычки ' '
sudo apt-get remove 'k3b.*'