O argumento para a opção -e
de rsync
não é uma linha de comando do shell, é uma linha de comando rsync
. rsync
analisa as suas próprias regras que diferem das de Bourne.
Como todos os shells, ele trata os caracteres de espaço como separadores de argumentos e, assim como os shells Bourne, trata as aspas simples e aspas duplas (mas não as barras invertidas) como operadores de cotação. Ele não faz nenhuma expansão de shell (como $var
, $(cmd)
, *.txt
, ~user
...).
Portanto, para incorporar um argumento arbitrário nessa pseudo linha de comando, você poderia incluí-lo entre aspas duplas, exceto o caractere de aspas duplas (que você incluiria entre aspas simples) ou incluí-las entre aspas simples, exceto para o único citar o próprio caractere (que você incluiria entre aspas duplas).
Por exemplo, se seu arquivo-chave ssh for /cygdrive/c/John Doe/.ssh/John "Dude" Doe's.rsa
, o argumento para -e
deve ser algo como '/cygdrive/c/John Doe/.ssh/John "Dude" Doe'"'"'s.rsa'
ou "/cygdrive/c/John Doe/.ssh/John "'"'"Dude"'"'" Doe's.rsa"
.
Você pode definir uma função dedicada para fazer isso rsync-quoting como:
# ksh93/bash/zsh syntax:
rsync_quote() {
local arg="$1"
arg=${arg//\'/\'\"\'\"\'}
printf "'%s'\n" "$var"
}
rsync -e "ssh -i $(rsync_quote "$sshkey") -p $dstport" ...
Outra opção seria passar um shell como argumento para -e
, que seria o interpretador da linha de comando ssh
. Uma vantagem disso é que o shell poderia fazer as expansões variáveis.
KEY=$sshkey PORT=$dstport SSH_COMMAND='ssh -i "$KEY" -p "$PORT" "$@"' \
rsync -e "sh -c 'eval \"\$SSH_COMMAND\"' sh" ...
Se você executá-lo com strace -fe execve -s 999
, será exibido:
execve("/usr/bin/rsync", ["rsync", "-e", "sh -c 'eval \"$SSH_COMMAND\"' sh", "1/", "localhost:2/"], 0x7ffc03b83678 /* 74 vars */) = 0
strace: Process 7208 attached
[pid 7208] execve("/bin/sh", ["sh", "-c", "eval \"$SSH_COMMAND\"", "sh", "localhost", "rsync", "--server", "-e.LsfxC", ".", "2/"], 0x7ffcc6ad0f28 /* 74 vars */) = 0
[pid 7209] execve("/usr/bin/ssh", ["ssh", "-i", "/cygdrive/c/John Doe/.ssh/John \"Dude\" Doe's.rsa", "-p", "2222", "localhost", "rsync", "--server", "-e.LsfxC", ".", "2/"], 0x5651a0c144a8 /* 74 vars */) = 0