Really struggling with getting a command argument variable to work with rsync. The behavior i'm seeing is this error from the script:

rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(601) [sender=3.0.7]

However the script outputs the command it's going to run via an echo, and the exact same command copy pasted into the terminal (or back into the script as the first line with a exit after it) works just fine ?!

Script code that does this rsync (check_flags is empty in this case):

rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- \"${backup_dir}\" \"admin@nas-1:${backup_basename}/\")

echo "CMD to run: rsync ${rsync_cmd[@]}"

rsync ${rsync_cmd[@]}


CMD to run: rsync -rWltpgoDvdHP --delete-before -- "/share/CACHEDEV1_DATA/veeam_backup_daily/Daily backup _@1am__1" "admin@nas-1:/share/CACHEDEV1_DATA/veeam_backup_daily/"

I've read online that using an array should help this issue, but it didn't in this case. I'm fairly sure this is an easy fix but it's driving me nuts !

  • the exact same command copy pasted into the terminal[...]works just fine So, in that case, from where comes your variables ? – user2196728 May 29 '15 at 1:56
  • i mean the output of the echo, pasted back into a terminal as a command. It seems like eval might be able to 'fix' the issue, but i'm not sure why that'd make a difference. – Sirex May 29 '15 at 2:00

The shell parses quotes before it substitutes variables, so including quotes in the variable's value doesn't do what you expect (and the echo is highly misleading because it doesn't show this distinction). What you should do is use unescaped quotes when defining the array (so they're parsed as delimiters around array elements, rather than part of the array value), then double-quote the reference to the array (so it doesn't word-split or wildcard-expand the values in the array). I'd also replace the echo command with a printf that'll show what's going to happen more accurately:

rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- "${backup_dir}" "admin@nas-1:${backup_basename}/")

printf "%q " CMD to run: rsync "${rsync_cmd[@]}"
printf "\n"

rsync "${rsync_cmd[@]}"

Note that the printf may not show what you expect -- it'll print an equivalent representation of the command that'll be executed, but there are many different equivalent representations of each argument, and it'll pick one based on its preferences, not how it was originally entered. BTW, you can also use set -x to debug things like this, but (as with printf "%q ") it may use a different representation than you expect.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.