Às vezes eu vejo scripts usam todas estas diferentes formas de citar algum texto: "..."
, '...'
, $'...'
, e $"..."
. Por que existem tantos tipos diferentes de cotação em uso?
Eles se comportam de maneira diferente ou afetam o que eu posso fazer dentro deles?
Respostas:
Tudo isso significa algo diferente, e você pode escrever coisas diferentes dentro deles (ou as mesmas coisas, com significado diferente). Diferentes tipos de citação interpretam diferentes seqüências de escape dentro deles (
\something
) ou permitem ou não permitem interpolações variáveis ($something
) e outros tipos de expansão dentro deles.Em resumo:
'...'
é inteiramente literal."..."
permite variáveis e caracteres de aspas incorporados.$'...'
executa escapes de caracteres como\n
, mas não expande variáveis.$"..."
é para traduções de idiomas humanos no Bash e no ksh.'Aspas simples'
Tudo o que você escreve entre aspas simples é tratado literalmente e não é processado. Barras invertidas e cifrões não têm significado especial lá. Isso significa que você não pode escapar da barra invertida de um caractere (incluindo outras aspas simples!), Interpolar uma variável ou usar qualquer outro recurso de shell.
Todos esses exemplos resultam literalmente no que está escrito entre as aspas:
A última é complicada - há duas cadeias de citação simples executadas em conjunto com algum texto não citado. O primeiro contém
I\
. O texto não citadodn\'t
contém uma única citação que é escapada no nível do shell , portanto, não inicia uma string entre aspas e é incluída como um caractere literal (assim,dn't
). A string final citada é apenasve
. Todos eles são reunidos em uma única palavra da maneira usual em que o shell funciona.Um idioma bastante comum para combinar texto literal e variáveis é executá-los juntos assim:
vai resultar em
como uma única palavra (é melhor citar duas vezes
$PATH
também, apenas por maiúsculas e minúsculas - espaços ou caracteres brilhantes no valor da variável podem ser processados de outra forma - mas por uma questão de exemplo legível, não o tenho)."Aspas duplas"
Dentro de aspas duplas, dois tipos de expansão são processados e você pode usar uma barra invertida para escapar de caracteres para impedir que expansões ou escapes sejam processadas.
Existem duas categorias de expansão que ocorrem entre aspas duplas:
$
( expansão de parâmetros$abc
e${abc}
, substituição de comando$(...)
, e expansão aritmética$((...))
);`abc`
;Dentro das aspas, uma barra invertida pode inibir essas expansões colocando-a antes do
$
or`
. Ele também pode escapar de uma citação dupla de fechamento, para\"
incluir apenas"
na sua string ou em outra barra invertida. Qualquer outra barra invertida é preservada literalmente - não há escapatória para produzir outros caracteres e não é removida.Alguns desses exemplos agem de maneira diferente de antes e outros não:
$ 'Cotação ANSI-C'
Esse tipo de citação permite que escapes de barra invertida no estilo C sejam processados, mas não variáveis ou substituições incorporadas. É o único tipo de citação que suporta escapes de caracteres .
Esta é uma extensão do ksh, agora suportada no Bash, zsh e em alguns outros shells. Não é ainda parte do padrão POSIX e scripts para maximamente-portáteis não podem usá-lo, mas um script Bash ou ksh é livre para.
Todos esses escapes podem ser usados com os seus significados C:
\a
,\b
,\f
,\n
,\r
,\t
,\v
, e os escapes literais\\
,\'
,\"
, e\?
. Eles também suportam as extensões\e
(caractere de escape) e no Bash e ksh\cx
(o que seria inserido por Ctrl-x , por exemplo,\cM
é retorno de carro). Os reservatórios têm uma série de extensões menores próprias.Ele também permite quatro tipos de escape de caracteres genéricos:
\nnn
, um único byte com valor octal nnn\xHH
, um único byte com valor hexadecimal HH\uHHHH
, o ponto de código Unicode cujo índice hexadecimal é HHHH\UHHHHHHHH
, o ponto de código Unicode cujo índice hexadecimal é HHHHHHHHTodos esses dígitos são opcionais após o primeiro.
$
e`
não têm significado e são preservadas literalmente, então você não pode incluir uma variável lá.A maioria desses escapes você pode simular usando o
printf
comando , embora POSIX requer apenas\\
,\a
,\b
,\f
,\n
,\r
,\t
,\v
, e\nnn
para trabalhar lá. Você pode usar substituição de comando para incorporar umprintf
dentro de aspas duplas se necessário:"Path:$(printf '\t')$PATH"
.$ "Tradução local"
Essa é uma extensão específica do ksh e do Bash para localizar seqüências de texto em idioma natural e procura a parte dentro das aspas em um catálogo de mensagens. Ele executa todas as expansões de aspas duplas primeiro. Se a sequência não for encontrada no banco de dados de tradução, ela será usada como sua própria tradução. A suposição interna é que as strings estão em inglês.
Você provavelmente não deseja usar este, mas se o vir, geralmente poderá tratá-lo como aspas duplas regulares.
Um ponto de observação é que não há nenhum tipo de citação que permita a expansão de parâmetros incorporados e os caracteres incorporados escapam. Na maioria dos casos em que você deseja isso, seria melhor (mais seguro) usar
printf
:Isso separa claramente quais partes estão sujeitas a escape de caracteres e quais são os valores dos dados.
Outra é que todos esses estilos de citação criam uma única "palavra" no shell, a menos que
$@
uma expansão de matriz${x[@]}
seja usada entre aspas duplas. Os dois formulários de aspas simples são sempre uma palavra e nunca se expandem mais.fonte
$"..."
também é do ksh93, adicionado ao bash no 2.0.\cX
dentrozsh
. É\CX
ou está\C-X
lá (\c
já tem um significado especialecho
)'let x="'$PATH\"
está errado em contextos lista em que não sejam conchaszsh
como$PATH
não é citado (assim estaria sujeito a divisão + glob que você não gostaria que aqui).