Ontem à noite eu estava tentando gravar CDs. Ficando irritado com o k3b e optando por usar o brasero, fui remover o k3b.
Eu digitei:
sudo apt-get remove k3b
Apertei a tecla tab duas vezes e vi que tinha os dados k3b e k3b no meu sistema. Supondo que não precisaria de dados k3b no meu sistema sem o k3b, também queria removê-los e digitei:
sudo apt-get remove k3b*
Infelizmente, apertei Y para confirmar sem olhar. Desinstalou muito mais do que k3b
e k3b-data
. Desinstalou pacotes que não se encaixavam no meu k3b*
regex. Por exemplo: transmission
e network-manager
.
Estou bastante certo de que eu não tinha um espaço entre k3b
e *
mas eu não sei porque senão ele iria remover tudo o que ele fez. Existe algo sobre o apt-get que estou entendendo mal?
apt
package-management
regex
Steve Goykovich
fonte
fonte
Respostas:
O comando que você deseja é
sudo apt-get remove '^k3b.*'
, porque:.*
combinar qualquer caractere, quantas vezes desejar^
coincidir com o início da string*
como curinga(Esta resposta completa e resume as informações anteriores fornecidas por qbi e Flimm)
fonte
.*
. Você pode apenas usarsudo apt-get remove ^k3b
. A presença de^
é suficiente para fazer com que o argumento seja interpretado como uma expressão regular e quandoapt
ouapt-get
interpreta um argumento como uma expressão regular, ele corresponde a qualquer lugar do nome do pacote. É por isso que você precisa^
- ancorar a correspondência no início do nome do pacote. A expressão regular não precisa corresponder ao nome inteiro do pacote, apenas a qualquer parte dele.^
, então você não precisa.*
)A expressão regular
*
representa zero ou arbitrariamente muitos. Então você disseapt-get
para remover qualquer coisa que contenhak3
seguida por qualquer número deb
, então basicamente tudo que contémk3
. Se eu tentar o seu comando no meu sistema, ele deseja remover 58 pacotes.fonte
*
funciona como um curinga para o bash, como no DOS, mas alguns comandosapt-get
esperam um regex. Quando você digitasudo apt-get remove -s k3b*
, o bash primeiro procura por arquivos no diretório atual que começam comk3b
. Se encontrar algum, substituirá esse argumento por esses nomes de arquivos. Caso contrário, ele passarák3b*
diretamente paraapt-get
, o que o interpretará como um regex. Se você não quer bash para interpretar o asterisco como um curinga primeiro (que você provavelmente não), coloque o argumento entre aspas simples, como este:sudo apt-get remove -s 'k3b*'
sudo apt-get remove -s 'k3b.*'
. Apenas encontrei esta resposta e achei realmente importante saber. IMHO isso é bastante inesperado e eu o marcaria como um bug de "comportamento inesperado" do apt-get ... você normalmente espera um significado "glob" e não um "regexp" se não for especificado. Obrigado mesmo assim e +1!-s
opção significa "simulação". Dizapt-get
para não executar a operação, mas simplesmente para informá-lo do que aconteceria sem a-s
opção.Use em
sudo apt-get remove ^k3b
vez disso. Quando você instala ou remove pacotes,*
geralmente é perigoso e raramente necessário. Se você usar*
, deve citá-lo, mas isso não o torna mais seguro, porque a tendência de selecionar muito mais pacotes do que você pretende é o resultado do caminhoapt
eapt-get
interpretá-lo, e não um efeito da expansão do nome do caminho .*
são muitas vezes desnecessários .k3b*
remove todos os pacotes que contêmk3
qualquer lugar em seu nome (e todos os pacotes que dependem desse pacote). Isso não é um erro de digitação -k3
é suficiente, mesmo sem ob
, porqueb*
significa "zero ou maisb
s".Quando você executa
apt
ouapt-get
com oinstall
,remove
oupurge
ação, cada argumento posterior é o primeiro 1 interpretado como o nome de um pacote individual. Se um pacote com esse nome exato existir, a ação será executada para ele.Se não existe tal pacote,
apt
eapt-get
irá verificar se o argumento contém qualquer um dos comuns de expressões regulares metacharacters 2.
,?
,+
,*
,|
,\[
,^
, ou$
. Caso contrário, está feito - nenhum pacote foi encontrado.Se ele não contém nenhum desses personagens, então ele é tratado como uma expressão regular e comparado com qualquer parte de qualquer nome do pacote. Não precisa corresponder ao nome inteiro. Como outros já disseram,
*
em uma expressão regular não significa a mesma coisa que*
em uma glob.?
também não. Em uma expressão regular:*
permite que o item anterior apareça inúmeras vezes - incluindo apenas uma vez ou não - em vez de exatamente uma vez.?
torna o item anterior opcional - ou seja, permite que ele apareça zero ou uma vez.O apt-get (8) (
man apt-get
) diz:A manpage apenas menciona
.
,?
e*
, mas é incompleta , como+
,|
,[
,^
, e$
também são suficientes para deixarapt-get
ouapt
interpretar o padrão como uma expressão regular. 3Embora você possa combinar qualquer número de caracteres com
.*
- e não apenas -, você*
só precisa disso se ele aparecer no meio da sua expressão regular. Como o padrão é comparado com qualquer substring de um nome de pacote, não faz sentido o final (ou o começo) do padrão.A página de manual menciona
^
e$
. Estes (especialmente^
) são a chave para escrever padrões seguras e eficientes para uso com osinstall
,remove
oupurge
ações emapt
ouapt-get
.^
ancora uma expressão regular no início de toda a cadeia.^k3b
seleciona todos os pacotes cujos nomes começam comk3b
.$
ancora uma expressão regular no final de toda a cadeia.k3b$
selecionaria todos os pacotes cujos nomes terminam comk3b
.Portanto, você pode usar este comando para remover com segurança os pacotes:
Finalmente, no caso específico que você mencionou, você também pode apenas passar os dois nomes:
Então você evita toda essa complexidade! (Embora a ancoragem com
^
seja simples quando você estiver acostumado a isso.) Ou use expansão de chaves , que seu shell expande no comando acima:1 Há duas excepções a esta: (a) algumas opções (por exemplo,
-f
,--purge
) são reconhecidos, e (b) alguns caracteres de pontuação que aparecem no final de um argumento que seria tomado como um nome de pacote para executar a ação pode ser usado para alterar o que é feito (por exemplo,sudo apt install ubuntu-desktop^
instala a tarefa em vez do pacote e quando^
aparece no final).2 Existem outros metacaracteres de expressão regular. Por exemplo,
\
é suportado por todos os dialetos de expressões regulares e comumente usado..
,?
,+
,*
,|
,[
,^
, E$
só acontecerá a ser os metacaracteres os desenvolvedores APT decidiram provocaria interpretação como uma expressão regular (após a resolução como um pacote exato nomeado falhou).3 A maneira mais fácil de verificar isso é simular a instalação ou remoção com esse padrão, usando a
-s
opção descrita acima. Por exemplo, a execução deapt -s install ^virtualbox
programas quesudo apt install ^virtualbox
teriam o efeito de tentar instalar todos os pacotes que o gerenciador de pacotes conhece sobre cujo nome começavirtualbox
. No entanto, esse comportamento também pode ser verificado examinando o código-fonte . Verifique aCacheSetHelper::PackageFromRegEx
função emcacheset.cc
.fonte
É mais provável que você remova uma lib que continha o k3b da qual esses programas dependiam.
Em resumo, você pode nunca saber. Eu recomendo não usar um curinga para remover e ler as coisas quando solicitado (desculpe).
Também sem as pesquisas -n regex, use todos os campos e não apenas nomes
http://ccrma.stanford.edu/planetccrma/man/man8/apt-cache.8.html
também qbi está correto seu regex é falho desde o início
fonte
apt-get remove
, apenas porapt-get cache
. Parece que, na verdade,apt-get remove
apenas procura nomes de pacotes, não descrições.