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.
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:
'hello world' => hello world
'/pkg/bin:$PATH' => /pkg/bin:$PATH
'hello\nworld' => hello\nworld
'`echo abc`' => `echo abc`
'I\'dn\'t've' => I\dn'tve
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 citado dn\'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 é apenas ve
. 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:
'let x="'$PATH\"
vai resultar em
let x="/usr/bin:/bin"
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).
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:
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:
"hello world" => hello world
"/pkg/bin:$PATH" => /pkg/bin:/bin:/usr/bin
"hello\nworld" => hello\nworld
"hello\\nworld" => hello\nworld
"`echo abc`" => abc
"I\'dn\'t've" => I\'dn\'t've
"I'dn't've" => I'dn't've
"I\"dn\"t've" => I"dn"t've
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 é HHHHHHHH
Todos 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á.
$'hello world' => hello world
$'/pkg/bin:$PATH' => /pkg/bin:$PATH
$'hello\nworld' => hello
world
$'`echo abc`' => `echo abc`
$'I\'dn\'t\'ve' => I'dn't've
$'\U1f574\u263A' => 🕴☺
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 um printf
dentro de aspas duplas se necessário: "Path:$(printf '\t')$PATH"
.
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
:
printf 'New path: \e[1m%s\e[0m' "/pkg/bin:$PATH:"
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.