Respostas:
Aspas simples não interpolam nada, mas as aspas duplas o fazem. Por exemplo: variáveis, backticks, certos \
escapes, etc.
Exemplo:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
O manual do Bash tem o seguinte a dizer:
Incluir caracteres entre aspas simples (
'
) preserva o valor literal de cada caractere entre aspas. Uma aspas simples pode não ocorrer entre aspas simples, mesmo quando precedida por uma barra invertida.Anexando caracteres entre aspas duplas (
"
) preserva o valor literal de todos os caracteres entre as aspas, com exceção de$
,`
,\
, e, quando a expansão história está habilitado,!
. Os caracteres$
e`
mantêm seu significado especial entre aspas duplas (consulte Expansões do Shell ). A barra invertida mantém o seu significado especial apenas quando seguido por um dos seguintes caracteres:$
,`
,"
,\
ou nova linha. Nas aspas duplas, as barras invertidas que são seguidas por um desses caracteres são removidas. As barras invertidas que precedem os caracteres sem um significado especial não são modificadas. As aspas duplas podem ser citadas entre aspas duplas, precedendo-a com uma barra invertida. Se ativado, a expansão do histórico será executada, a menos que uma!
aparição entre aspas duplas seja escapada usando uma barra invertida. A barra invertida anterior ao!
não é removida.Os parâmetros especiais
*
e@
têm significado especial entre aspas duplas (consulte Expansão dos parâmetros do shell ).
git_prompt
que o git fornece, eles sugerem usá-lo assim PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
, git prompt , de acordo com isso não deve funcionar. Existe algo de especial nas PS#
variáveis? ou por que funciona se não está fazendo a interpolação.
PS1
. Tente echo $PS1
ver o que eu quero dizer. Mas PS1
é avaliado antes de ser exibido (consulte a PROMPTING
seção na página de manual do bash). Para testar isso, tente PS1='$X'
. Você não terá nenhum aviso. Em seguida, execute X=foo
e de repente seu prompt é "foo" (havia PS1
sido avaliado quando definido em vez de exibido, você ainda não teria nenhum prompt).
A resposta aceita é ótima. Estou fazendo uma tabela que ajuda na rápida compreensão do tópico. A explicação envolve uma variável simples a
, bem como uma matriz indexada arr
.
Se definirmos
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
e então echo
a expressão na segunda coluna, obteríamos o resultado / comportamento mostrado na terceira coluna. A quarta coluna explica o comportamento.
# | Expression | Result | Comments
---+-------------+-------------+--------------------------------------------------------------------
1 | "$a" | apple | variables are expanded inside ""
2 | '$a' | $a | variables are not expanded inside ''
3 | "'$a'" | 'apple' | '' has no special meaning inside ""
4 | '"$a"' | "$a" | "" is treated literally inside ''
5 | '\'' | **invalid** | can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
6 | "red$arocks"| red | $arocks does not expand $a; use ${a}rocks to preserve $a
7 | "redapple$" | redapple$ | $ followed by no variable name evaluates to $
8 | '\"' | \" | \ has no special meaning inside ''
9 | "\'" | \' | \' is interpreted inside "" but has no significance for '
10 | "\"" | " | \" is interpreted inside ""
11 | "*" | * | glob does not work inside "" or ''
12 | "\t\n" | \t\n | \t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13 | "`echo hi`" | hi | `` and $() are evaluated inside ""
14 | '`echo hi`' | `echo hi` | `` and $() are not evaluated inside ''
15 | '${arr[0]}' | ${arr[0]} | array access not possible inside ''
16 | "${arr[0]}" | apple | array access works inside ""
17 | $'$a\'' | $a' | single quotes can be escaped inside ANSI-C quoting
18 | "$'\t'" | $'\t' | ANSI-C quoting is not interpreted inside ""
19 | '!cmd' | !cmd | history expansion character '!' is ignored inside ''
20 | "!cmd" | cmd args | expands to the most recent command matching "cmd"
21 | $'!cmd' | !cmd | history expansion character '!' is ignored inside ANSI-C quotes
---+-------------+-------------+--------------------------------------------------------------------
Veja também:
The special parameters * and @ have special meaning when in double quotes
então como é que "*"
resulta *
?
"$@"
e "$*"
são expansões de parâmetros. "@"
e "*"
não é.
echo "\'"
me devolve \'
.
Se você estiver se referindo ao que acontece quando ecoar algo, as aspas simples literalmente ecoarão o que você tem entre elas, enquanto as aspas duplas avaliarão variáveis entre elas e produzirão o valor da variável.
Por exemplo, isso
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
vai dar o seguinte:
double quotes gives you sometext
single quotes gives you $MYVAR
Outros explicaram muito bem e só querem dar com exemplos simples.
Aspas simples podem ser usadas em torno do texto para impedir que o shell interprete caracteres especiais. Cifrões, espaços, e comercial, asteriscos e outros caracteres especiais são todos ignorados quando colocados entre aspas simples.
$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
Isso dará o seguinte:
All sorts of things are ignored in single quotes, like $ & * ; |.
A única coisa que não pode ser colocada entre aspas simples é uma aspas simples.
As aspas duplas atuam de maneira semelhante às aspas simples, exceto que as aspas duplas ainda permitem que o shell interprete sinais de dólar, aspas e barras invertidas. Já se sabe que as barras invertidas impedem que um único caractere especial seja interpretado. Isso pode ser útil entre aspas duplas se um cifrão precisar ser usado como texto em vez de como uma variável. Ele também permite que aspas duplas sejam escapadas para que não sejam interpretadas como o final de uma sequência de caracteres citada.
$ echo "Here's how we can use single ' and double \" quotes within double quotes"
Isso dará o seguinte:
Here's how we can use single ' and double " quotes within double quotes
Também pode ser notado que o apóstrofo, que de outra forma seria interpretado como o início de uma seqüência de caracteres citada, é ignorado entre aspas duplas. As variáveis, no entanto, são interpretadas e substituídas por seus valores entre aspas duplas.
$ echo "The current Oracle SID is $ORACLE_SID"
Isso dará o seguinte:
The current Oracle SID is test
As aspas anteriores são totalmente diferentes das aspas simples ou duplas. Em vez de serem usadas para impedir a interpretação de caracteres especiais, as aspas na verdade forçam a execução dos comandos que eles incluem. Depois que os comandos incluídos são executados, sua saída é substituída no lugar das aspas na linha original. Isso ficará mais claro com um exemplo.
$ today=`date '+%A, %B %d, %Y'`
$ echo $today
Isso dará o seguinte:
Monday, September 28, 2015
Existe uma distinção clara entre o uso de ' '
e " "
.
Quando ' '
é usado em torno de qualquer coisa, não há "transformação ou tradução" feita. É impresso como está.
Com " "
, o que quer que esteja ao redor, é "traduzido ou transformado" em seu valor.
Por tradução / transformação, quero dizer o seguinte: Qualquer coisa entre aspas simples não será "traduzida" para seus valores. Eles serão tomados como estão entre aspas. Exemplo:, a=23
então echo '$a'
produzirá $a
na saída padrão. Considerando que echo "$a"
irá produzir 23
na saída padrão.
Como essa é a resposta de fato ao lidar com aspas bash
, acrescentarei mais um ponto esquecido nas respostas acima, ao lidar com os operadores aritméticos no shell.
O bash
shell suporta duas formas de operação aritmética, uma definida pelo let
comando interno e pelo $((..))
operador. O primeiro avalia uma expressão aritmética, enquanto o último é mais uma declaração composta.
É importante entender que a expressão aritmética usada let
sofre expansão de nome de caminho e divisão de palavras, como qualquer outro comando do shell. Portanto, é necessário fazer uma citação e escape adequados.
Veja este exemplo ao usar let
let 'foo = 2 + 1'
echo $foo
3
O uso de aspas simples aqui é absolutamente bom aqui, como não há necessidade de expansões variáveis aqui, considere um caso de
bar=1
let 'foo = $bar + 1'
falharia miseravelmente, pois as $bar
aspas simples não se expandiriam e precisam ser citadas duas vezes como
let 'foo = '"$bar"' + 1'
Esse deve ser um dos motivos, $((..))
sempre deve ser considerado o uso excessivo let
. Porque dentro dele, o conteúdo não está sujeito à divisão de palavras. O exemplo anterior usando let
pode ser simplesmente escrito como
(( bar=1, foo = bar + 1 ))
$((..))
sem aspas simplesEmbora $((..))
possa ser usado com aspas duplas, não há objetivo, pois o resultado não pode conter um conteúdo que necessite de aspas duplas. Apenas certifique-se de que não esteja entre aspas simples.
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
Em alguns casos especiais do uso do $((..))
operador dentro de uma única cadeia de caracteres entre aspas, é necessário interpolar aspas de maneira que o operador fique sem aspas ou entre aspas duplas. Por exemplo, considere um caso, quando você está tentando usar o operador dentro de uma curl
instrução para passar um contador toda vez que uma solicitação é feita, faça
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
Observe o uso de aspas duplas aninhadas dentro, sem as quais a cadeia literal $((reqcnt++))
é passada para o requestCounter
campo.
$((...))
também. É poderia ser "um pouco" paranóico e bastante improvável que tenha IFS=0
, por exemplo, mas certamente não é impossível :)
$[[...]]
sintaxe herdada, mas talvez você tenha razão em esquecê-la.