7

I am writing bash script, which in some part will rsync files over ssh. Unfortunately I am facing problem with keeping rsync options as variable. Please take a look below:

    # variables
    directory="/etc"
    backupDirectory="/backup"
    incrementalBackup="/incremental"
    options="-a -e 'ssh -p 10022' -b --backup-dir=$incrementalBackup --delete"
    # rsync
    rsync $options user@server:$directory $backupDirectory

Unfortunately above script fails with rsync error:

    Unexpected remote arg: user@server:/etc
    rsync error: syntax or usage error (code 1) at main.c(1201) [sender=3.0.6]

What I saw during script debugging is the fact, that ssh options ('ssh -p 10022') are treated as rsync options. The question is how to pass correctly those additional ssh settings into rsync? Thanks in advance for a tip.

umläute
  • 28,885
  • 9
  • 68
  • 122
Piotr
  • 173
  • 1
  • 2
  • 11

2 Answers2

14

Use an array; it's why they were added to bash:

# variables
directory="/etc"
backupDirectory="/backup"
incrementalBackup="/incremental"
options=(-a -e 'ssh -p 10022' -b --backup-dir="$incrementalBackup" --delete)
# rsync
rsync "${options[@]}" user@server:"$directory" "$backupDirectory"

eval is not a safe option to use; it isn't limited to just evaluating the quotations you intend it to, but will evaluate any code. It might work for your current situation, but changes to the value of options might bring unforeseen consequences, and it's generally a bad idea to get into the habit of using eval when it isn't necessary.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • I actually wanted to say: `One option is to use eval`. +1 for the alternate. – devnull Oct 07 '13 at 12:58
  • 3
    What is the reason we need to use array or eval with rsync? I mean for other commands, I typically use variable which shell would have replaced before calling the program anyways? – Bhaskar Dec 03 '14 at 20:53
4

Use eval. Try:

eval rsync $options user@server:$directory $backupDirectory
devnull
  • 118,548
  • 33
  • 236
  • 227