Se o arquivo realmente contiver '/home/*'
, com as aspas, as aspas estarão lá no valor de excludestr
no loop e, em seguida, no argumento que você fornecer a rsync
. Eles não fazem parte de um comando shell nesse caso, apenas parte do valor expandido da substituição de comandos.
Por outro lado, se você escrever exclude_String+=(--exclude='/home/*')
, agora as aspas são parte de um comando shell e são removidas durante o processamento desse comando. (Com o efeito de tornar *
um caractere comum.)
rsync
na verdade não espera ou processa cotações como parte do padrão de exclusão, ele apenas os tratará como qualquer outro caractere e excluirá arquivos com nomes contendo citações. Então, se você tem os padrões de exclusão como dados em algum arquivo, você não deve ter as citações lá.
Além disso, em vez de for x in $(cat file)
, use while IFS= read -r line; do ...; done < file
ou, neste caso, mapfile -t exclude_String < file
. Essa substituição de comando com cat
chama a divisão de palavras, portanto, você não pode ter padrões de exclusão contendo espaço em branco. Ele também invoca globbing dos padrões imediatamente, ali mesmo, na lista de palavras para o loop for
. Não é isso que você quer.
Em geral, o que você precisa é:
excludes=()
while IFS= read -r line; do
excludes+=(--exclude="$line")
done < ./list
rsync "$flags" "${excludes[@]}" . "$destination"
Com ./list
contendo apenas os padrões a serem excluídos:
/home/*
*.vim*
(As aspas em torno de "$line"
in +=(--exclude="$line")
impedem que o shell gere arquivos chamados --exclude=something
no diretório atual.)
Embora no caso de rsync
, você também pode usar --exclude-from
:
rsync "$flags" --exclude-from=./list . "$destination"
Se você for usar algo mais complicado que um arquivo para alimentar o loop, poderá usar a substituição de processo:
while IFS= read -r line; do
excludes+=(--exclude="$line")
done < <(some command that produces the exclude patterns)
Veja também: Por que minha variável local está em um loop 'while read', mas não em outro loop aparentemente similar?