No Mac, coloque um padrão curinga entre aspas simples para impedir que o shell padrão zsh o expanda antes da execução do comando. Por exemplo, printf '%s\n' '*.csv' passa o texto literal *.csv como um único argumento. As aspas são removidas pelo shell; o asterisco chega ao programa. Se o próprio programa usar padrões, ele poderá interpretar esse asterisco posteriormente.

Por que o caractere curinga muda antes da execução do comando

Quando você digita um comando no Terminal, o shell processa seus argumentos antes de iniciar o programa. No zsh, um * sem aspas pode acionar a geração de nomes de arquivos: o shell substitui o padrão pelos nomes de arquivos correspondentes. Se não houver correspondências, o zsh normalmente relata um erro, embora as opções do shell possam alterar esse comportamento. O manual do zsh descreve a geração de nomes de arquivos e seu comportamento quando não há correspondência.

A Apple define o zsh como o shell padrão no Terminal, embora um Mac possa ser configurado para usar outro shell. O guia do Terminal da Apple explica o padrão e como alterá-lo. O método com aspas simples abaixo é adequado para o zsh e o Bash; se você usa um shell diferente, consulte seu manual, pois as regras de citações podem variar.

Use aspas simples para um caractere curinga literal

Digite o padrão curinga entre aspas simples, preservando quaisquer outros caracteres que pertençam a ele. Por exemplo:

printf '%s\n' '*.csv'

A saída é o literal *.csv, quer o diretório atual contenha arquivos CSV ou não. O printf recebe o padrão como argumento e o imprime; o shell não expande o asterisco. As aspas são sintaxe do shell, portanto não são incluídas no argumento. O guia de shell scripting da Apple explica que as aspas simples desativam a expansão do shell dentro do texto entre aspas. Apple: Flow Control, Expansion, and Parsing.

Isso é especialmente importante quando se espera que o próprio programa manipule um padrão. No macOS, por exemplo, o find pode corresponder nomes de arquivos usando o padrão fornecido para -name:

find . -type f -name '*.log'

Aqui, o shell passa *.log literalmente para o find; depois, o find aplica sua própria correspondência de nomes de arquivos aos arquivos sob o diretório atual. O uso de aspas impede que o shell substitua o padrão por nomes no diretório atual antes que o find possa usá-lo. O significado do padrão depende do programa de destino: o uso de aspas no shell controla a expansão do shell, não como o programa interpreta seu argumento.

Quando usar uma barra invertida

Para um padrão curto, uma barra invertida pode proteger um caractere curinga individual fora de aspas:

printf '%s\n' \*.csv

Isso também passa o asterisco literalmente. Aspas simples costumam ser mais fáceis de ler quando um padrão contém vários caracteres especiais, espaços ou colchetes. Por exemplo, 'chapter [0-9]*.txt' impede que os colchetes e o caractere curinga sejam interpretados pelo shell. A Apple documenta o escape com barra invertida e o comportamento das aspas simples em seu guia de shell scripting.

Erros comuns ao usar aspas

Aspas duplas não protegem todos os caracteres do shell de forma confiável. Elas impedem a expansão de curingas no zsh, mas ainda permitem certas expansões, incluindo variáveis como $name e substituições de comandos como $(command). Para um padrão que deve chegar exatamente como digitado, use aspas simples, a menos que o argumento precise de uma dessas expansões.

Uma aspa simples não pode aparecer dentro de uma string entre aspas simples como um caractere comum. Se o próprio padrão contiver um apóstrofo/aspa simples, feche a parte entre aspas, adicione o apóstrofo usando outro método de citação e reabra as aspas simples; a Apple mostra essa técnica de citação de shell em seu guia. Para padrões incomuns, inspecione o comando exato cuidadosamente antes de executá-lo.

Distinga também a expansão do shell do comportamento do programa que recebe o argumento. Colocar *.log entre aspas não força um programa a tratar o asterisco como um caractere comum; apenas garante que o shell o repasse. Um utilitário como find -name pode interpretá-lo como um padrão, enquanto outro comando pode tratá-lo literalmente. Verifique a documentação desse comando quando a distinção for importante.

Uma verificação rápida antes de pressionar Return

Pergunte-se o que o programa deve receber. Se ele precisar de um padrão curinga, coloque o padrão entre aspas simples e confirme se as opções do comando estão configuradas para interpretar padrões conforme o pretendido. Se o programa deve receber um nome de arquivo real, deixe a expansão do shell ativada onde for apropriado ou forneça o nome do arquivo diretamente. O segredo é usar aspas no limite do shell quando você quiser que o programa receba os próprios caracteres curinga.

Fontes