LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Rsync gives error but only when called via bash script (https://www.linuxquestions.org/questions/linux-newbie-8/rsync-gives-error-but-only-when-called-via-bash-script-4175496290/)

KroniK 02-26-2014 11:12 AM

Rsync gives error but only when called via bash script
 
I have been working on a backup script that uses rsync to do an incremental backup.

I have tested the following rsync command manually, and it runs and completes a backup without error:

Code:

rsync -aAXv --delete --progress --link-dest=/backup/Uyuk/Uyuk-backup-part1/2014-02-24/ /mnt/backup/ /backup/Uyuk/Uyuk-backup-part1/2014-02-25/
however when I run that same command in my backup script it gives me the following error:

Code:

rsync: -aAXv --delete --progress --link-dest=/backup/Uyuk/Uyuk-backup-part1/2014-02-24/ /mnt/backup/ /backup/Uyuk/Uyuk-backup-part1/2014-02-25/: unknown option
    rsync error: syntax or usage error (code 1) at main.c(1422) [client=3.0.6]

I ran bash -x on my script to figure out exactly what is sent to the console and here is what was printed:

Code:

+ rsync '-aAXv --delete --progress --link-dest=/backup/Uyuk/Uyuk-backup-part1/2014-02-24/ /mnt/backup/ /backup/Uyuk/Uyuk-backup-part1/2014-02-25/'
Does anyone see what is wrong? I cant find anything that would cause the syntax error.


EDIT:
Here is the actual code I have in the script, and this is a pretty large script so yes some variables are not defined here, but you get the idea.

Code:

mkdir -p "/backup/$HOST/$NAME/$TODAY"
#source directory
SRC="$MNT"
#link directory
LNK="/backup/$HOST/$NAME/$LAST/"
#target directory
TRG="/backup/$HOST/$NAME/$TODAY/"
#rsync options
OPT1="-aAXv --delete --progress --link-dest=$LNK"

#run the rsync command
echo "rsync $OPT1 $SRC $TRG"
rsync "$OPT1 $SRC $TRG" > /var/log/backup/backup.rsync.log 2>&1


suicidaleggroll 02-26-2014 11:18 AM

Remove the quotes in your rsync call. Quotes break rsync's ability to parse the individual arguments.

For example:
Code:

-aAXv --delete
Should expand to
Code:

-aAXv
and
Code:

--delete
two separate arguments inside rsync. But by putting quotes around it you're forcing rsync to treat it as ONE argument, which is invalid.

If you want to play around with how arguments will expand given your quoting style, put this into a new code:
Code:

#!/bin/bash
for i in "$@"; do
  echo $i
done

and then replace "rsync" in your call with this new script name and see what it prints

For example
Code:

$ ./script a b c
a
b
c
$ ./script "a b" c
a b
c

And using your call:
Code:

$ HOST=host
$ NAME=name
$ TODAY=today
$ LAST=last
$ SRC="$MNT"
$ LNK="/backup/$HOST/$NAME/$LAST/"
$ TRG="/backup/$HOST/$NAME/$TODAY/"
$ OPT1="-aAXv --delete --progress --link-dest=$LNK"
$ ./script "$OPT1 $SRC $TRG"
-aAXv --delete --progress --link-dest=/backup/host/name/last/ /backup/host/name/today/

when it SHOULD look like
Code:

$./script $OPT1 $SRC $TRG
-aAXv
--delete
--progress
--link-dest=/backup/host/name/last/
/backup/host/name/today/

You should inject some spaces into your host, name, today, last, and src variables to make sure everything is handled properly.

Also, variable names in all caps are generally reserved for environment variables rather than local script variables. It improves readability later on.

rknichols 02-26-2014 11:24 AM

Quote:

Originally Posted by KroniK (Post 5125114)
Code:

rsync "$OPT1 $SRC $TRG" > /var/log/backup/backup.rsync.log 2>&1

The way you have the entire set of arguments quoted it is being presented to rsync as a single argument, and since that begins with '-' it is interpreted as a (mostly illegal) set of options. You can leave OPT1 unquoted and quote the SRC and TRG arguments individually.
Code:

rsync $OPT1 "$SRC" "$TRG" > /var/log/backup/backup.rsync.log 2>&1
That will have a problem if $LNK contains white space. You might keep that out of OPT1 and include it explicitly.
Code:

rsync $OPT1 --link-dest="$LNK" "$SRC" "$TRG" > /var/log/backup/backup.rsync.log 2>&1
[EDIT] There's an echo in here.

KroniK 02-26-2014 12:41 PM

Essentially these replies were correct, so thank you! I ended up putting all the arguments in an array and then calling the array.

Here is the modified code:

Code:

mkdir -p "/backup/$HOST/$NAME/$TODAY"
#source directory
SRC="$MNT"
#link directory
LNK="--link-dest=/backup/$HOST/$NAME/$LAST/"
#target directory
TRG="/backup/$HOST/$NAME/$TODAY/"
#rsync options
OPT1=( "-aAXv" "--delete" "--progress" "$LNK" )

#run the rsync command
echo "rsync ${OPT1[@]} $SRC $TRG"
rsync "${OPT1[@]}" "$SRC" "$TRG" > /var/log/backup/backup.rsync.log 2>&1

The above setup fixed all problems and it works fine now :D


All times are GMT -5. The time now is 08:28 PM.