Alguém pode explicar o que “$ {files [@]}” faz?

1

Estou escrevendo um script para zipar arquivos antigos e, em exemplos on-line, encontrei o abaixo. Eu gostaria de saber em detalhes o que o "${files[@]}" faz ou como ler os caracteres especiais. "${files[@]}"

files=($(find /var/cdrs -maxdepth 1 -name \*.C*R -mtime +150))
tar cvfz /var/cdrs_backup/CDRBackup_$(date +%Y%m%d_%H%M%S).tar.gz "${files[@]}"
    
por Matthew Rahm 30.08.2016 / 21:14

3 respostas

0

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.

    
por 30.08.2016 / 21:35
0

O files=(...) cria uma matriz de nomes de arquivos

A sintaxe "${files[@]}" significa _todo o elemento da matriz; ou seja, cada nome de arquivo encontrado. Observe que o "..." surround é importante para impedir que alguns nomes de arquivos sejam divididos.

(Isso pode falhar se algum nome de arquivo tiver um retorno de carro).

    
por 30.08.2016 / 21:21
0

files=(...) cria uma matriz de strings em ksh , que criou esta sintaxe, e em shells que a adotaram mais tarde como bash e outras.

$(find /var/cdrs -maxdepth 1 -name \*.C*R -mtime +150) cria uma lista, separada por espaços, de nomes de caminho que correspondem às condições especificadas. No entanto, se um nome de arquivo contiver um dos caracteres IFS, normalmente espaço, tabulação e avanço de linha, o nome do arquivo será dividido em partes e, em seguida, será armazenado incorretamente na matriz.

"${files[@]}" é expandido para uma lista de strings em que cada elemento é citado. Citando os elementos é inútil aqui como a matriz não pode conter espaços, tabulações ou retornos de carro de qualquer maneira, conforme indicado no parágrafo anterior. Esta sintaxe pode ser ligeiramente simplificada aqui por ${files[*]} .

    
por 30.08.2016 / 22:13