Use sudo apt-get remove ^k3b
instead. When you install or remove packages, *
is often dangerous and rarely needed. If you do use *
, you should quote it, but that does not make it safer, because its tendency to select far more packages than you intend is the result of the way apt
and apt-get
interpret it and not an effect of pathname expansion.
- Even safe uses of
*
are often unnecessary.
- Unsafe uses are brutal. Removing
k3b*
removes every package that contains k3
anywhere in its name (and every package that depends on such a package). That's not a typo--containing k3
is sufficient, even without the b
, because b*
means "zero or more b
s."
When you run apt
or apt-get
with the install
, remove
, or purge
action, each subsequent argument is first1 interpreted as the name of an individual package. If a package with that exact name exists, the action is performed for it.
If there is no such package, apt
and apt-get
will check if the argument contains any of the common regular expression metacharacters2 .
, ?
, +
, *
, |
, \[
, ^
, or $
. If not, it's done--no package was found.
If it does contain any of those characters, then it is treated as a regular expression and matched against any part of any package name. It doesn't have to match the whole name. As others have said, *
in a regular expression doesn't mean the same thing as *
in a glob. ?
doesn't either. In a regular expression:
*
allows the previous item to appear any number of times--including just once or not at all--instead of exactly once.
?
makes the previous item optional--that is, it allows it to appear zero or one times.
apt-get(8) (man apt-get
) says:
If no package matches the given expression and the expression contains
one of '.', '?' or '*' then it is assumed to be a POSIX regular
expression, and it is applied to all package names in the database.
Any matches are then installed (or removed). Note that matching is
done by substring so 'lo.*' matches 'how-lo' and 'lowest'. If this is
undesired, anchor the regular expression with a '^' or '$' character,
or create a more specific regular expression.
The manpage only mentions .
, ?
, and *
, but it is incomplete, as +
, |
, [
, ^
, and $
are also sufficient to let apt-get
or apt
interpret the pattern as a regular expression.3
Although you can match any number of any characters with .*
--not just *
--you only need this if it would appear in the middle of your regular expression. Because the pattern is matched against any substring of a package name, it's pointless at the end (or beginning) of the pattern.
The manpage mentions ^
and $
. These (especially ^
) are key to writing safe, efficient patterns for use with the install
, remove
, or purge
actions in apt
or apt-get
.
^
anchors a regular expression to the beginning of the whole string. ^k3b
selects all packages whose names start with k3b
.
$
anchors a regular expression to the end of the whole string. k3b$
would select all packages whose names end with k3b
.
Therefore you can use this command to safely remove the packages:
sudo apt-get remove ^k3b
Finally, in the specific case you mentioned, you might as well just pass both names yourself:
sudo apt-get remove k3b k3b-data
Then you avoid all this complexity! (Though anchoring with ^
is simple once you're used to it.) Or use brace expansion, which your shell expands into the above command:
sudo apt-get remove k3b{,-data}
1 There are two exceptions to this: (a) some options (e.g., -f
, --purge
) are recognized, and (b) some punctuation characters appearing at the end of an argument that would otherwise be taken as a package name to perform the action can be used to alter what is done (e.g., sudo apt install ubuntu-desktop^
installs the task rather than the package, and when ^
appears at the end ).
2 Other regular expression metacharacters exist. For example, \
is supported by all dialects of regular expressions and commonly used. .
, ?
, +
, *
, |
, [
, ^
, and $
just happen to be the metacharacters the APT developers decided would trigger interpretation as a regular expression (after resolution as an exact package named has failed).
3 The easiest way to verify this is to simulate installation or removal with such a pattern, using the -s
option as described above. For example, running apt -s install ^virtualbox
shows that sudo apt install ^virtualbox
would have the effect of attempting to install every package the package manager knows about whose name begins with virtualbox
. However, this behavior can also be verified by examining the source code. Check the CacheSetHelper::PackageFromRegEx
function in cacheset.cc
.