Em vez de criar a lista de nomes de arquivos e padrões como uma única string, você pode criar uma matriz para começar:
list=(file1 dir1 "**.data" "**.source")
e, em seguida, percorre os elementos:
args=()
for item in "${list[@]}" ; do
args+=(--filter="+ $item")
done
Isso criaria argumentos como --filter=+ file1
, sem nenhuma aspas dentro da string de argumento. (Você não deseja que as aspas entrem em rsync
. Ele reclamará de uma regra de filtro que as possui, por exemplo, rsync "--filter='+ foo'" ...
)
E quando você passar a matriz para o comando, use "${args[@]}"
para passar os elementos da matriz como strings distintas:
rsync "${args[@]}" "$srcdir" "$destdir"
Em vez de "--filter=+ foo"
, acho que você poderia usar apenas --include=foo
. Isso removeria um espaço problemático dos argumentos (mas não faria nada sobre espaços ou globs nos padrões de nome de arquivo).
No seu caso, você usou set -f
para desabilitar a globbing, for i in $list
deve funcionar, mas como você precisa de uma matriz, é melhor usar uma para começar.
Mais importante ainda, a atribuição args=${arr[*]}
achata a matriz para uma única string. Agora os espaços dentro dos argumentos e os espaços entre os argumentos são iguais, há apenas --filter=+ file1 --filter=+ dir1 ...
e a shell não tem como diferenciar os diferentes tipos de espaço em branco. A expansão sem aspas $args
será dividida em todo e qualquer espaço em branco (que a saída set -x
mostra, se você quiser analisar a confusão de aspas).
Com efeito, todos os ganhos de usar uma matriz foram discutidos nesta tarefa.