Em suma, você cria uma matriz files e a expande.
Você lê assim:
VAR=... significa que você está atribuindo uma variável. VAR=(...) significa que você está atribuindo uma matriz bash a uma variável.
$(...) significa que você está executando um comando e capturando sua saída, no seu caso, a lista de arquivos que correspondem ao padrão fornecido que são tão antigos e, em seguida, atribuem cada arquivo a um elemento em uma matriz bash.
${...} significa que você está lendo o valor de uma variável, por exemplo:
$ SOMEVAR="a value"
$ echo "${SOMEVAR}"
a value
No bash $VAR e ${VAR} são equivalentes, mas a notação ${VAR} permite que você faça algumas coisas extras. Mais notavelmente echo "${VAR}iable" expandirá a variável $VAR e concatenará com a string iable , enquanto echo $VARiable tentará expandir a variável $VARiable . Você também pode fazer alguma substituição avançada usando a notação ${...} .
No nosso caso, estamos lendo a variável de arquivo com ${file...} . Em seguida, o [...] indica que estamos lendo uma matriz bash . Então, estamos tentando acessar um elemento da matriz de arquivos, o bit dentro de [...] informa quais elementos, isso pode ser 1 para acessar o primeiro elemento, 2 para acessar o segundo e assim por diante (bash arrays são indexados de 1 não 0). @ significa todos os elementos, então estamos tentando acessar todos os elementos da matriz bash chamada file .
Você pode experimentá-lo com o seguinte:
% ARRAY=("a value" "another value" "fred")
% for x in "${ARRAY[@]}"; do echo "$x"; done
a value
another value
fred
A vantagem de usar matrizes apenas sobre strings separadas por espaços é que você pode incluir espaços nos valores, como acima. Portanto, no seu caso, cada arquivo na matriz files será tratado como um argumento separado e os espaços nos nomes dos arquivos serão tratados corretamente.
Então, basicamente, seu snipit encontra e coleta uma lista de arquivos e os transmite como argumentos individuais para o comando tar.