Por que o uso de '*' não funciona sempre no zsh?

4

eu corri o seguinte comando no zsh

sudo apt-get install rhythmbox* 

Produziu um erro, quando eu corri o mesmo comando no bash funcionou. Por que isso acontece?

Como posso fazer o comando acima funcionar em zsh?

    
por banarun 26.06.2013 / 17:34

3 respostas

8

Veja o que acontece

O Bash tentará avaliar o padrão rhythmbox* no diretório de trabalho atual. Como é muito improvável que haja qualquer arquivo ou diretório começando com a seqüência de rhythmbox , ele não será expandido, mas o Bash fornecerá isso como um argumento para apt-get aqui.

Observe que, se você tiver um arquivo com o nome rhythmbox-test , ele não funcionará, pois ele será expandido e rhythmbox-test será fornecido como o argumento para apt-get .

Solução: escapa ou cita!

Portanto, para usar de forma confiável os padrões em apt-get em um shell Bash, você deve sempre evitá-lo. Use aspas ou a barra invertida, por exemplo,

sudo apt-get install rhythmbox\* 

ou

sudo apt-get install "rhythmbox*"

Sobre o mesmo vale para o zsh.

A expansão do padrão é chamada de globbing .

Demo

touch aa ab  # creates files aa and ab
ls a*        # lists both files as Bash provided ls two arguments.
ls 'a*'      # No such file or directory. Bash provided literally a* to ls.
ls a\*       # No such file or directory. Same as above.
    
por gertvdijk 26.06.2013 / 17:43
3

Você precisa usar aspas para evitar que o zsh expanda o '*' (você quer que o apt-get expanda o *)

sudo apt-get install "rhythmbox*"
    
por Panther 26.06.2013 / 17:41
1

Use ^rhythmbox (com ^ ). Geralmente, evite * ao instalar ou remover pacotes.

Mesmo se você cite então o shell não foi alterado , * não faz o que a maioria das pessoas espera quando aparece em um nome de pacote com a maioria das ações apt / apt-get , incluindo install , remove e purge . Evite * no padrão que segue essas ações, a menos que você saiba exatamente o que faz e por quê. Geralmente * não é o que você realmente quer e esse é um daqueles momentos em que parece que você não o faz. * não não significa "qualquer caractere" neste contexto.

A maneira correta de informar apt-get para instalar todos os pacotes cujos nomes iniciam com rhythmbox é:

sudo apt-get install ^rhythmbox

Isso também funciona com apt install . Da mesma forma, se você precisar remover esses pacotes, poderá especificar ^rhythmbox após a ação remove ou purge .

^rhythmbox corresponde a todos os nomes de pacotes que iniciam com rhythmbox porque ^ is a âncora de início de linha (ou, neste caso, início de cadeia) .

O problema com * no nome de um pacote para instalar ou remover é que apt e apt-get interprete-a como uma expressão regular em vez de uma glob . Em uma expressão regular, * significa "zero ou mais do item anterior". Então, quando você executar sudo apt-get install com rhythmbox\* , 'rhythmbox*' , "rhythmbox*" ou (quando o shell não expande * ) rhythmbox* , na verdade você está dizendo apt-get para instalar todos os pacotes com rhythmbo em qualquer lugar nome.

  • Não é rhythmbox , rhythmbo , porque o x deve aparecer qualquer número de vezes - zero ou mais vezes.
  • Não no início do nome ou como o nome completo, mas em qualquer lugar em seu nome.

No caso específico de este pacote específico, isso provavelmente não causará grandes problemas, pois provavelmente há poucos pacotes que possuem rhythmbo em seus nomes, mas não iniciam com rhythmbox . Mas com pacotes cujos nomes são mais curtos, especialmente ao usar as ações remove ou purge , isso é muitas vezes desastroso .

A principal exceção a isso é apt list . A list action faz interpretar * e ? como globbing caracteres em vez de metacaracteres de expressões regulares. Então você pode procurar por pacotes cujos nomes começam com rhythmbox desta forma:

apt list rhythmbox\*

(ou com 'rhythmbox*' ou "rhythmbox*" .)

Mas para instalar tais pacotes - e não instalar mais pacotes do que você quer dizer - você ainda precisa usar:

sudo apt install ^rhythmbox

Ou você pode simplesmente passar os nomes de pacotes específicos de que precisa. Usar apt list pode ajudá-lo a encontrá-los.

    
por Eliah Kagan 25.08.2017 / 13:42