Seus três exemplos não são exatamente iguais.
Nos dois últimos:
if [ "${a}" == 0 ]; then
ffmpeg -framerate 2 -pattern_type glob -i "*.png" -pix_fmt yuv420p output.mp4
Se $a
não foi citado e seu valor continha caracteres de $IFS
(por espaço padrão, tabulação e nova linha) ou caracteres curinga, isso
faça com que [
receba mais de três argumentos (além dos [
e ]
), resultando em um erro;
da mesma forma, se o valor de $a
fosse a cadeia vazia, isso causaria
[
para receber poucos argumentos:
$ (a=0; [ $a == 0 ] && echo OK)
OK
(mas somente se $IFS
atualmente não contiver 0
)
$ (a='foo bar'; [ $a == 0 ] && echo OK)
bash: [: too many arguments
(com o valor padrão de $IFS
)
$ (a=; [ $a == 0 ] && echo OK)
bash: [: ==: unary operator expected
(mesmo com um $IFS
vazio ou com zsh
(que, de outra forma, não implementa o operador split + glob implícito em expansões sem aspas))
$ (a='*'; [ $a == 0 ] && echo OK)
bash: [: too many arguments
(quando executado em um diretório que contenha pelo menos dois arquivos não ocultos).
Com cotação, sem erro:
$ (a='foo bar'; [ "$a" == 0 ] && echo OK)
$ (a=; [ "$a" == 0 ] && echo OK)
Seu primeiro exemplo é diferente. As regras sobre expansão dentro
as aspas duplas são especiais quando as matrizes estão envolvidas; se a
denota um
array, então:
-
$a
é o primeiro elemento da matriz (em geral, é${a[0]}
, mesmo que o elemento no indice 0 não esteja definido); -
${a[*]}
ou${a[@]}
são os elementos da matriz, adicionalmente divididos em$IFS
(espaço, tabulação, nova linha por padrão); -
"${a[@]}"
são os elementos da matriz, não divididos em$IFS
.
Portanto, o seu loop for i in "${indices[@]}"; do ...
não funciona
o mesmo, dependendo do conteúdo da matriz. Por exemplo:
$ (declare -a a=(a b c); printf '%s\n' $a)
a
$ (declare -a a=(a b c); printf '%s\n' ${a[*]})
a
b
c
$ (declare -a a=(a 'b c'); printf '%s\n' ${a[*]})
a
b
c
$ (declare -a a=(a 'b c'); printf '%s\n' ${a[@]})
a
b
c
$ (declare -a a=(a 'b c'); printf '%s\n' "${a[*]}")
a b c
$ (declare -a a=(a 'b c'); printf '%s\n' "${a[@]}")
a
b c