Qual é a diferença entre
aspas envolvem apenas o valor da opção
por exemplo:
grep --file="grep pattern file.txt" *
contra
aspas envolvem o nome da opção e o valor da opção
por exemplo:
grep "--file=grep pattern file.txt" *
?
Eles produzem o mesmo resultado.
Aspas e barras invertidas em shells são usadas para remover o caráter especial de alguns caracteres, para que sejam tratados como caracteres comuns.
As aspas duplas são especiais porque ainda permitem que expansões ocorram internamente. Ou seja, dentro deles
$
,\
e`
ainda são especiais. Eles também afetam o modo como essas expansões são executadas.Nessa linha, os únicos caracteres especiais do shell são:
*
, que é um operador de padrão glob, e a presença de tal caractere, quando não citado em uma linha de comando simples, aciona um mecanismo chamado geração de nome de arquivo ou globbing ou expansão de nome de caminho (o texto POSIX).Os outros caracteres não têm significado especial na sintaxe do shell.
Aqui, o que queremos fazer é que o shell execute o
/usr/bin/grep
arquivo com estes argumentos:grep
--file=grep pattern file.txt
Então nós queremos:
*
para ser tratado como um operador glob e ser expandido para os arquivos não ocultos no diretório de trabalho atual.Portanto, os caracteres acima não devem ser citados.
No entanto, existem dois desses espaços que queremos incluir no segundo argumento passado para
grep
, portanto, eles devem ser colocados entre aspas. Então, no mínimo, precisamos:Ou:
(para mostrar diferentes operadores de cotação)
É aí que citamos apenas os 2 caracteres que são especiais para o shell e que não queremos que sejam tratados como tal. Mas também poderíamos fazer:
E cite todos os caracteres, exceto aqueles que queremos que o shell trate de maneira especial.
Citar esses caracteres não especiais não faz diferença para o shell¹.
Aqui, alternar diferentes formas de cotações funcionaria da mesma forma.
Dado que os nomes de comandos e opções² raramente contêm caracteres especiais do shell, é comum não colocá-los entre aspas. Você raramente vê pessoas fazendo
'ls' '-l'
em vez dels -l
, então essegrep --file="the value"
é um avistamento comum, mesmo que não faça diferença em comparação comgrep "--file=the value"
ougrep --file=the" value"
.Consulte Como usar um caractere especial como normal em shells Unix? para obter mais detalhes sobre quais caracteres são especiais e maneiras de citá-los em vários shells.
Agora isso ainda deixa alguns problemas com esse comando:
*
começar com-
, será tratado como uma opção*
expande todos os arquivos, independentemente do tipo. Isso inclui diretórios, links simbólicos, fifos, dispositivos. Provavelmente, você deseja procurar apenas arquivos do tipo regular (ou pode criar links simbólicos para arquivos regulares)--file
é um GNUísmo. O equivalente padrão é com-f
.*
expandir para apenas um arquivo,grep
não incluirá o nome do arquivo junto com as linhas correspondentes.*
não corresponder a nenhum arquivo, em alguns shells, incluindo o bash (por padrão), um*
argumento literal será passado paragrep
(e provavelmente reclamará que não é possível abrir um arquivo com esse nome).Então, aqui, você gostaria de usar o shell zsh, por exemplo, e escrever:
Onde:
-f
é usado no lugar de--file
.--
marca o fim da opção para que nenhum outro argumento depois dela seja tratado como um, mesmo que comece com-
./dev/null
paragrep
que sejam passados pelo menos 2 arquivos, garantindo que sempre imprimirá o nome do arquivo.*(-.)
issogrep
apenas em arquivos regulares . Se não corresponder a nenhum,zsh
será abortado com um erro de não correspondência e não executará o grep.Como estamos passando
/dev/null
paragrep
, também poderíamos adicionar oN
qualificador glob (*(N-.)
) que faria com que o glob se expandisse para nada quando não houvesse correspondência, em vez de relatar um erro, egrep
apenas olharia para dentro/dev/null
(e falharia silenciosamente).¹ Cuidado ao citar palavras-chave na sintaxe do shell, como
while
,do
,if
,time
mesmo em parte, tem uma influência, pois impede que o shell as reconheça como tal; da mesma forma,'v'ar=value
impediria que o shell considerasse uma atribuição de variável, pois'v'ar
não é um nome de variável válido (e o tratamento de aspas é executado após a análise da sintaxe). Ou seufoo
alias não será expandido se você os escrever\foo
ouf'oo'
a menos que você também tenha aliases para os formulários citados (o que poucos shells permitem que você faça)² Com a notável exceção de
-?
algumas vezes encontradas em utilitários inspirados nos da Microsoft.³ No caso do GNU
grep
, isso também se aplica a outros argumentos, não apenas ao primeiro, já que o GNUgrep
(e hoje em dia algumas outras implementações semelhantes ao GNU) aceita opções mesmo após argumentos sem opção.