I would like to use custom identity file when using rsync, but only if the file exists, otherwise I don't want to bother with custom ssh command for rsync. I am having problems with quotes. See examples.
Desired command if identity file exists
rsync -e "ssh -i '/tmp/id_rsa'" /tmp/dir/ u@h:/tmp/dir
Desired command if identity file does not exist
rsync /tmp/dir/ u@h:/tmp/dir
I wanted to create a variable that would contain -e "ssh -i '/tmp/id_rsa'"
and use it as follows
rsync ${identityArg} /tmp/dir/ u@h:/tmp/dir
This variable would be either empty or contain desired ssh command.
An example way I fill the variable (I have tried many ways)
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg="-e 'ssh -i \"${IDENTITY_FILE}\"'"
fi
The problem is that quotes are always wrong in the command and I end up with commands similar to these ones (set -x
is set in the script and this is the output)
rsync -e '\ssh' -i '"/tmp/id_rsa"'\''' /tmp/dir/ u@h:/tmp/dir
There is something I do not get about quotation in bash. If you have any good resource about usage of single and double quotes in bash script I would like to read it.
You want to add two positional parameters: -e
and ssh -i '/tmp/id_rsa'
, where /tmp/id_rsa
is an expanded variable. You should use an array for this:
args=(/tmp/dir/ u@h:/tmp/dir)
idfile=/tmp/id_rsa
# Let [[ ... ]] do the quoting
if [[ -f $idfile ]]; then
# Prepend two parameters to args array
args=(-e "ssh -i '$idfile'" "${args[@]}")
fi
rsync "${args[@]}"
I'm not convinced the inner single quotes are necessary for ssh -i
, but this expands to exactly the commands shown in the question.