Esse $'...'
em bash
não é expansão de parâmetro, é um tipo especial de cotação introduzido por ksh93
que expande os códigos \n
, \x0a
, para um caractere de nova linha.
zsh
também adicionou \u000a
. ksh93
e bash
também têm \cj
, enquanto zsh
tem \C-J
. ksh93
também suporta variações como \x{a}
.
O $
é uma sugestão de que é alguma forma ou expansão. Mas em qualquer caso, ele difere de outras formas de expansões que usam $
(como $((1 + 1))
, $param
ou $(cmd)
), pois não é executado dentro de aspas duplas ou aqui documentos ( echo "$'x'"
outputs $'x'
em todos os shells, embora não seja especificado por POSIX) e sua expansão não está sujeita a split + glob, é definitivamente mais próxima de um operador de cotação do que de um operador de expansão.
IFS=\n
definiria o IFS como n
( \
é tratado como um operador de cotação) e IFS="\n"
ou IFS='\n'
configuraria o IFS para as barras invertidas de dois caracteres e n
.
Você também pode usar:
IFS='
'
ou
IFS="
"
ou
IFS=$'
'
Para passar uma nova linha literal, embora seja menos legível (e não se pode ver nada além de usar coisas como set list
in vi
se $IFS
contiver outros caracteres de espaçamento nesse código).
IFS=:
, IFS=':'
, IFS=":"
, IFS=$':'
todos definem o IFS como :
, portanto, não importa qual você usar.
$'...'
é suportado (com variações) por pelo menos: ksh93
, zsh
, bash
, mksh
, busybox sh
, FreeBSD sh
. ksh93
e bash
também têm uma forma de aspas $"..."
usada para localização de texto, embora raramente seja usada, pois é difícil de implantar e usar de maneira portável e confiável.
As conchas es
e fish
também podem usar \n
fora das cotações para expandir para a nova linha.
Algumas ferramentas como printf
, algumas implementações de echo
ou awk
também podem expandir essas \n
por si mesmas. Por exemplo, pode-se fazer:
printf '\n'
awk 'BEGIN{printf "\n"}'
echo
echo '\n\c' # UNIX compliant echos only
para a saída do caractere de nova linha, mas observe que:
IFS=$(printf '\n')
não funcionará porque a substituição de comando ( $(...)
) retira todos os caracteres de nova linha à direita. Você pode no entanto usar:
eval "$(printf 'IFS="\n"')"
O que funciona porque a saída de printf
termina em um caractere "
, não em uma nova linha.
Agora, para conclusão, no rc
shell e derivados (como es
ou akanga
), $'\n'
é de fato a expansão dessa variável \n
(uma variável cujo nome é a sequência de dois caracteres \
e n
). Essas shells não têm uma limitação em quais caracteres os nomes das variáveis podem conter e possuem apenas um tipo de aspas: '...'
.
$ rc
; '\n' = (foo bar)
; echo $'\n'
foo bar
; echo $'\n'(1)
foo
As variáveis rc
também são exportadas para o ambiente, mas pelo menos na variante Unix de rc
, para nomes de variáveis como \n
, a versão da variável de ambiente passa por uma forma de codificação:
; env | grep foo | sed -n l
__5cn=fooIFS='
'
1bar$
( 0x5c
sendo o valor de byte de ASCII \
; veja também como essa variável de matriz foi codificada com um byte 0x1 como o separador).