2 ms·
Ah, double quotes handling can be another nightmare as well, can't make this work: function backup { local SOURCE=$1 local DESTINATION=$2
by liendolucas 3y ago
Ah, double quotes handling can be another nightmare as well, can't make this work:
function backup {
local SOURCE=$1
local DESTINATION=$2
local ID_RSA=$3
# VALID_SSH is hard-coded for testing.
local VALID_SSH="yes"
local REMOTE_SHELL=""
if [[ "${VALID_SSH}" == "yes" ]]; then
REMOTE_SHELL='-e "ssh -i '${ID_RSA}'"'
fi
rsync -av \
--no-perms \
--links \
$(if [[ "${VALID_SSH}" == "yes" ]]; then echo "${REMOTE_SHELL}"; fi) \
"${SOURCE}" "${DESTINATION}"
}
As it is when calling the function:
backup "." "backup@redstar.local:" "id_rsa"
rsync complains with:
Missing trailing-" in remote-shell command.
rsync error: syntax or usage error (code 1) at main.c(438) [sender=3.1.3]
But if I echo the `rsync` instead of calling it, its output is perfectly valid it actually
runs as expected:
rsync -av --no-perms --links -e "ssh -i id_rsa" . backup@redstar.local:
Been fiddling yesterday and today with no luck, it must be something very subtle. Tried a bunch of different things
from SO suggestions but none seem to work. Meh.
- o11c 3y agoAs a rule, `printf %q` or `${var@Q}` are very useful when building up quoted command strings. But your main problem is that `REMOTE_SHELL` is a string, when you need an array. Though I suppose you could make it a string if you used `eval` around its whole use.
- fragmede 3y agoHave you tried REMOTE_SHELL="-e \"ssh -i ${ID_RSA}\"" already?
- liendolucas 3y agoYup, same result. I've tried many small variations around the escaping of the double quotes, all with the same result. I haven't kept all of them but definitely tried your approach.
- fragmede 3y agoOh it's the $(if [[ "${VALID_SSH}" == "yes" ]]; then echo "${REMOTE_SHELL}"; fi) \ Change that to $(if [[ "${VALID_SSH}" == "yes" ]]; then echo ${REMOTE_SHELL}; fi) \ and have REMOTE_SHELL="-e \"ssh -i '${ID_RSA}'\""
- liendolucas 3y agoNo, is not :-). With that approach the "-e" gets eaten, producing: rsync -av --no-perms --links "ssh -i id_rsa" . backup@redstar.local: But, you can re-insert it in the if with: $(if [[ "${VALID_SSH}" == "yes" ]]; then echo -e "\055e ${REMOTE_SHELL}"; fi) \ and removing the "-e" from the REMOTE_SHELL var. Then... Same error as before!
- deleted 3y ago[deleted]
- fragmede 3y agoClever. Stopping to think about this, I think setting REMOTE_SHELL="" when it doesn't want to get used, and then inserting it every time, instead of using the conditional rsync ... ${REMOTE_SHELL} ... should also work. If it's empty, then it won't add anything, but if there's something then it'll get passed in.
- liendolucas 3y agoUpdate, this seems to work: function backup { local SOURCE=$1 local DESTINATION=$2 local ID_RSA=$3 local VALID_SSH="yes" local RSYNC_OPTIONS=(-av --no-perms --links) if [[ "${VALID_SSH}" == "yes" ]]; then RSYNC_OPTIONS+=(-e "ssh -i ${ID_RSA}") fi rsync "${RSYNC_OPTIONS[@]}" "${SOURCE}" "${DESTINATION}" } I got lucky and found this information with an explanation at: https://www.mail-archive.com/search?l=bug-bash@gnu.org&q=subject:%22help+with+rsync+and+Missing+trailing%5C-%5C%22+in+remote%5C-shell+command.%22&o=newest&f=1 https://www.mail-archive.com/search?l=bug-bash@gnu.org&q=sub... So, is it a good advice to always use bash arrays to construct arbitrary options for commands?