Bash não executa divisão de palavras em globbing nestes casos:
- LHS ou RHS de uma atribuição, exceto para matrizes indexadas
var=$value # simple variable declare -A hash key="key with a space" hash[$key]=$value # index of an associative array arr=$(echo "1 2 3") # word splitting does happen here
- Lado de dentro
[[ ]]
var="one two" if [[ $var = *" "* ]]; then ... # check if var has a space in it if [[ $(echo "one two") = $var ]]; then # use the output of command substitution to compare with var
- Lado de dentro
(( ))
((sum = $(echo "99 + 1"))) # assigns 100 to sum
- Em herestring
cat <<< * # gives '*' as the output
Existe uma lista definitiva de casos em que o Bash executa ou não a divisão e a globagem de palavras?
Normalmente, esses são os casos em que não pode ou não faria sentido, portanto, os contextos não listados. Existem no entanto contextos não listados onde o faz, mas reclama quando resulta em mais do que um item, ou junta esses itens com espaços.
Além disso, é importante fazer a distinção entre apenas correspondência de padrão curinga e geração ou globbing de nome de arquivo, que é a geração de uma lista de nomes de arquivo que correspondem a um padrão.
Por exemplo, em
[[ foo = * ]]
, não há globbing, pois*
não é expandido para a lista de arquivos não ocultos no diretório atual, mas*
ainda é interpretado como um padrão (aqui retorna true conformefoo
corresponde ao*
padrão).Ao dividir aqui, estamos nos referindo à divisão implícita que é feita na expansão de parâmetro sem aspas (
$param
), substituição de comando ($(...)
e`...`
) e expansão aritmética ($((...))
e$[...]
), usando o$IFS
parâmetro especial em contextos de lista .Tomaremos
*
como exemplo a seguir. Como padrão, corresponde a qualquer sequência de caracteres. Como um glob, ele se expande para todos os arquivos não ocultos no diretório atual (sujeito adotglob
,GLOBIGNORE
...).O abaixo se aplica a
bash
, existem variações em outros shells.Casos em que não ocorre splitting e globbing:
quando citado (com
'*'
,"*"
,\*
,$'*'
,$"*"
).dentro dos documentos aqui (esteja o delimitador entre aspas ou não):
dentro de expressões aritméticas:
echo $((2 * 2))
(*
não é globbed mas$((...))
sofre split+glob, tente depoisIFS=4
)array[2 * 2]=4
/${array[2 * 2]}
/exec {array[2*2]}>&1
. Lembre-se de que você precisa das aspas emunset -v 'a[1]'
([1]
é um curinga).((2 * 2))
echo $[2 * 2]
atribuição de variável escalar:
var=*
array[x]=*
hash[key]=*
array=([1]=*)
(versões mais antigasbash
costumavam fazer globbing lá e fazer algo diferente quando havia um arquivo chamado1=foo
no diretório atual, por exemplo).var+=*
em chaves de array associativas:
typeset -A hash; hash[**]=value; v=${hash[**]}
.*
e@
são especiais embora.em atribuições após
export
/local
/typeset
/declare
/readonly
apenas em algumas circunstâncias: a palavra-chave de atribuição e o nome da variável e=
não devem ser citados nem mesmo em parte e não ser o resultado de qualquer expansão. atribuições e redirecionamentos podem ocorrer antes, mascommand
não podem ser usados.:export a=*
x=1 < /dev/null export foo a=*
""export a=*
(exceto no modo POSIX)command export a=*
export "a"=*
export a\=*
"$(echo export)" a=*
mais sobre isso em As aspas são necessárias para a atribuição de variáveis locais?
case * in (...); esac
case x in (*); esac
(sem split+glob, mas isso*
é tratado como um padrão, que também se aplica ao curinga encontrado dentro de expansões sem aspas como emvar=*; case x in ($var)
).dentro
[[...]]
. Observe que a correspondência de padrões é feita se curingas sem aspas estiverem presentes no lado direito dos operadores=
,==
, .!=
aqui strings desde a versão 4.4. Nas versões anteriores, a divisão (mas não a globbing) era feita e as palavras resultantes eram unidas por espaços.
no alvo de redirecionamentos quando o shell está no modo POSIX e não interativo:
bash -o posix -c 'echo test > *
. Caso contrário, split+glob será executado ebash
reportará um erro se for expandido para uma lista com menos ou mais de 1 elemento.