Você deseja usar a opção -s|--protect-args
para rsync
.
Sem ele, a parte após o :
é passada como está para o shell remoto, então você pode usar construções desse shell para construir a lista a ser transferida.
Dessa forma, se você sabe que o shell remoto é zsh, por exemplo, você pode fazer:
rsync host:'*(.)' there
para transferir apenas arquivos regulares. Ou com csh
/ bash
/ zsh
/ ksh
:
rsync host:'{foo,bar}.txt' there
Ou:
rsync file 'host:"$HOME/$(uname)-file"'
Agora, isso significa que você não pode transferir arquivos com um nome arbitrário.
Com -s
, rsync
não passa a string para o shell remoto. Em vez disso, ele passa em banda para o servidor rsync
no host remoto, portanto não há interpretação pelo shell remoto.
(
e )
sendo especiais para a maioria dos shells, você teria que escapar usando a sintaxe do shell remoto, e isso varia de shell para shell.
O melhor é usar -s
.
rsync -sazR output.mp4 [email protected]:'encoded/somepath/DRRS_(H264).mp4'
No entanto, rsync
ainda executa (sua própria) globbing na string que você passa (mesmo para o destino!). Então você ainda não pode passar nomes de arquivos arbitrários com rsync
. Se você quiser processar um arquivo chamado *
, por exemplo, você precisa escapar com barra invertida (pelo menos, desta vez, independentemente do shell remoto).
rsync -sazR output.mp4 [email protected]:'\*'
Então, para transferir um arquivo com um nome arbitrário contido em $1
, você vai querer usar:
file=$1
rsync_escaped_file=$(
printf '%s.\n' "$file" | sed 's/[[*?]/\&/g'
)
rsync_escaped_file=${rsync_escaped_file%.}
rsync -s ... "user@host:$rsync_escaped_file"
Se o seu shell local for bash
e você souber que o shell de login do usuário remoto também é bash
da mesma versão, alternativamente, você pode usar printf %q
para escapar dos caracteres especiais do shell remoto e não use -s
:
LC_ALL=C printf -v shell_escaped_file %q "$1"
rsync ... "user@host:$shell_escaped_file"
Se você sabe que o shell de login do host remoto é parecido com Bourne (Bourne, ksh, yash, zsh, bash, ash ...) e seu cliente e servidor ssh permite passar LC_*
de variáveis de ambiente, você também pode do (novamente, sem -s
):
LC_FILE=$1 rsync ... 'user@host:"$LC_FILE"'
Note1 : a opção -s
| --protect-args
está disponível apenas na versão 3.0.0 (2008) ou acima
Note2 : a documentação rsync
avisa que -s
| --protect-args
pode se tornar o padrão em versões futuras de rsync
(para ser à prova do futuro, você pode deseja começar a usar --no-protect-args
se você não quiser seu efeito)