tags:

views:

442

answers:

1

I normally use scp to copy stuff, but now I'm trying to get used to the more powerful rsync command. It helps me use less bandwidth by copying up only files that have changed. However, rsync has a lot of complex parameters, so I thought, hey, I'll just make a little Bash script that makes it easy for me, and call the command 'rscp'. So, off I went building something like this. Note in the example below that my web host uses a different port number besides 22, so that's why the $1 is used for that.

#!/bin/bash

rsync -avzp --progress --rsh='ssh -p$1' $2 $3 $4 $5 $6 $7

So, its usage, I hoped, would be something like:

rscp 3822 --exclude=tiny_mce /var/www/mysite/* [email protected]:~/www/mysite

That would make it a little bit closer to my usage of the scp command, you see.

However, when I ran this, I get this error:

building file list ... 
4 files to consider
ERROR: destination must be a directory when copying more than 1 file
rsync error: errors selecting input/output files, dirs (code 3) at main.c(494) [receiver=2.6.9]
rsync: connection unexpectedly closed (8 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(454) [sender=2.6.9]

But if I go back to the regular rsync command, it works just fine.

Can anyone figure out what I'm doing wrong in my Bash script?

+7  A: 

/var/www/mysite/* is expanded by the shell, so you have many more arguments being passed in than you're handling in the script.

Also variables aren't substituted in single quotes, so you need to use double quotes. (See bash man page)

Try this:

#!/bin/bash
PORT=$1
shift
rsync -avzp --progress --rsh="ssh -p$PORT" "$@"

First we take the port off the argument list (with shift), then we use "$@" which is special, it refers to the argument (to the script in this case), and is converted to all of them, but each separately in double quotes. (see the bash man page for more details).

Douglas Leeder