Seu problema de citação está vindo de você tentando resolver um problema que você não tem. A necessidade de citar argumentos só entra em jogo quando você está lidando com um shell, e se find
estiver chamando rsync
diretamente, não há shell envolvido. Usar a saída visual não é uma boa maneira de saber se funciona ou não porque você não consegue ver onde cada argumento começa e termina.
Veja o que quero dizer:
# touch "foo'\"bar"
# ls
foo'"bar
# find . -type f -exec stat {} \;
File: ‘./foo'"bar’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 1659137 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1004/ phemmer) Gid: ( 1004/ phemmer)
Access: 2017-12-09 13:21:28.742597483 -0500
Modify: 2017-12-09 13:21:28.742597483 -0500
Change: 2017-12-09 13:21:28.742597483 -0500
Birth: -
Observe que não citei o {}
no argumento para stat
.
Agora, o seu comando será muito pouco performático, porque você está chamando rsync
para cada arquivo correspondente. Existem duas maneiras de resolver isso.
Como outros indicaram, você pode usar o pipe da lista de arquivos para rsync
em stdin:
# find . -type f -print0 | rsync --files-from=- -0 . dest/
# ls dest/
foo'"bar
Isso usará bytes nulos como o delimitador do nome do arquivo, pois os arquivos não podem conter bytes nulos em seu nome.
Se você estiver usando o GNU find
, você tem outro método de invocar -exec
, e isso é -exec {} +
. Neste estilo find
passará mais de um argumento por vez. No entanto, todos os argumentos são adicionados ao final do comando, não no meio. Você pode resolver isso passando os argumentos por meio de um pequeno shell:
# find . -type f -exec sh -c 'rsync "$@" dest/' {} +
# ls dest/
foo'"bar
Isso irá passar a lista de arquivos para o sh
, que irá substituí-los pelo "$@"