Colocar citações em algum texto desativa as expansões, como expansão de curingas e expansão de chaves. Uma maneira lógica de lembrar disso é que eles produzem uma lista de palavras, mas contextos como as citações garantem que o conteúdo seja uma única palavra.
Além disso, você tem vírgulas espúrias. Em um script de shell, as palavras são separadas por espaços.
declare -a backup_files=(*.{id,nsf} "desktop8.ndk" "user.dic")
Você pode escrever isso como
backup_files=(*.{id,nsf} "desktop8.ndk" "user.dic")
a menos que você também queira declarar backup_files
como uma variável local em uma função.
Observe que, se um dos padrões não corresponder a nenhum arquivo, ele não será expandido. Por exemplo, em um diretório vazio, você terminará com os quatro elementos *.id
, *.nsf
, desktop8.ndk
e user.dic
. Se você só vai passar isso para rm -f
, não importa. Mais geralmente, você pode lidar com isso verificando se cada elemento é um arquivo existente durante o processamento, por exemplo,
for x in "${backup_files[@]}"; do
if [[ ! -e "$x" ]]; then continue; fi
…
done
(Incidentalmente, note que acessar os elementos de uma matriz é uma exceção à regra que uma string entre aspas resulta em uma palavra em vez de uma lista de palavras. Com a expansão da matriz, as aspas duplas asseguram que cada elemento termina como uma única palavra, em vez de passar por correspondência de padrões e divisão de palavras. Isso, incluindo variantes como "$@"
, é a única exceção.
Como alternativa, você pode definir a opção nullglob
para tornar o resultado de correspondência de padrão em uma lista vazia quando não corresponder a nenhum arquivo.
shopt -s nullglob
backup_files=(*.{id,nsf} "desktop8.ndk" "archive" "user.dic")
Em seguida, a matriz conterá apenas os arquivos .id
e .nsf
existentes, mas conterá desktop8.ndk
e user.dic
, não importa o quê. Você pode organizar para excluir esses arquivos, se eles não existirem, tornando-os um padrão também.
shopt -s nullglob
backup_files=(*.{id,nsf} desktop8.nd[k] archiv[e] user.di[c])
Observe que as chaves e o caractere curinga são expandidos quando a matriz é definida. Assim, os padrões correspondem aos arquivos no diretório atual. Seu script está fazendo algo estranho e, provavelmente, não intencional: você está reunindo nomes de arquivos no diretório atual e copiando arquivos de nome idêntico de um diretório diferente $notes_data_directory
. Se você quiser combinar arquivos em um diretório diferente, você precisa dizer isso.
notes_data_directory=~/Library/Application\ Support/IBM\ Notes\ Data/
notes_backup_directory=~/Desktop/Notes\ Backup
backup_files=("$notes_data_directory/"*.{id,nsf} "$notes_data_directory/desktop8.ndk" "$notes_data_directory/archive" "$notes_data_directory/user.dic")
for i in "${backup_files[@]}"
do
cp -nipvR "$i" "$notes_backup_directory"
done
Você pode usar a expansão de chaves para reduzir a definição de backup_files
:
backup_files=("$notes_data_directory/"{*.{id,nsf},desktop8.ndk,archive,user.dic})
Alternativamente, mude para o diretório antes de copiar.
notes_data_directory=~/Library/Application\ Support/IBM\ Notes\ Data/
notes_backup_directory=~/Desktop/Notes\ Backup
cd "$notes_data_directory"
shopt -s nullglob
backup_files=(*.{id,nsf} desktop8.nd[k] archiv[e] user.di[c])
for i in "${backup_files[@]}"
do
cp -nipvR "$i" "$notes_backup_directory"
done
No entanto, outra abordagem é armazenar uma lista de padrões na matriz e usar a variável sem aspas para expandir os padrões. Observe que a expansão da chave precisa ocorrer no momento em que a linha do código-fonte é analisada, enquanto os curingas precisam ser armazenados não expandidos na matriz. Se houver algum espaço em branco no padrão, ele precisa ser citado; acertar isso é um pouco complicado. Eu não recomendo essa abordagem, é difícil de seguir. Como um padrão pode ou não acabar correspondendo a um arquivo, mas cp
requer pelo menos um arquivo de origem, é necessário manipular o caso em que o padrão corresponde ao arquivo zero separadamente.
notes_data_directory=~/Library/Application\ Support/IBM\ Notes\ Data/
notes_backup_directory=~/Desktop/Notes\ Backup
backup_patterns=(\*.{id,nsf} "desktop8.nd[k]" "archiv[e]" "user.di[c]")
# equivalent to backup_patterns=("*.id" "*.nsf" "desktop8.nd[k]" "archiv[e]" "user.di[c]")
shopt -s nullglob
for i in "${backup_patterns[@]}"
do
files=("$notes_data_directory/"$i)
if [[ ${#files[@]} -ne 0 ]]; then
cp -nipvR "${files[@]}" "$notes_backup_directory"
fi
done