Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

The following is a snip of output from bash -vx on my backup script

\+ rsync '' -avushi --stats --progress --log-file=/home/bigbird/temp/rlog/rlog1.txt /media/dataspace/data/webcasts/ /media/work/data/webcasts

sending incremental file list

I've been doing rsyncs like this forever and I just saw this problem in the last month or two. This one is running on Kubuntu Oneiric, but I think I may have seen it on Kubuntu Lucid as well.

The script is being run from /home/bigbird/bin

It works perfectly except that it additionally transfers all the files from my current directory to the destination. I also have a second rsync later in the script that does the same thing to another directory.

I just ran it again from another directory and it copied all of those files instead.

I don't see a "." in the source anywhere etc.

I did a set | less

Looked at all my ~/bin files

Looked at all my aliases

I don't have a clue as to what would be causing this.

Where do I look for the problem?

share|improve this question
    
I was able to reproduce this locally and when I removed the '' from your command it worked fine. –  bassburner Mar 13 '12 at 21:26
    
Can you show the original command as it appears in the script? –  enzotib Mar 13 '12 at 21:35
    
@andybarilla: Thanks. I figured that out just before I read your comment. I'm posting my answer as soon as the forum will let me (in another 4 hours). The remaining question is why didn't I get a syntax error? –  Joe Mar 14 '12 at 0:29

2 Answers 2

up vote 0 down vote accepted

Original code was

DRYRUN="-n"
DRYRUN=""
...

rsync "${DRYRUN}" -avushi --stats --progress --log-file="${LOGFILE}"
 /media/dataspace/data/webcasts/ "${MOUNT}${DESTDIR}"

Working code is

DRYRUN=1      ## for testing rsync without any file transfers
DRYRUN=0    ## for live run
...
if (( ${DRYRUN} ))
then
  rsync -n -avushi --stats --progress --log-file="${LOGFILE2}" /media/dataspace"${DESTDIR2}"/ "${MOUNT}${DESTDIR2}"
else
  rsync    -avushi --stats --progress --log-file="${LOGFILE2}" /media/dataspace"${DESTDIR2}"/ "${MOUNT}${DESTDIR2}"
fi

"We have met the enemy, and he is us!" - Walt Kelly (Pogo comic strip)

I found it! Invisible doesn't mean it's not there.

I don't quite understand what happened, but, by putting "${DRYRUN}" in the rsync command line it made the first argument to rsync "". Apparently that got interpreted as PWD instead of as an error. So the command was transfer "" and my real source to my real destination because rsync accepts multiple sources.

The remaining question is why does rsync think that "" means current directory instead of interpreting it as a syntax error?

share|improve this answer
    
The file arguments can be of the form user@host:path. I don't know how rsync parses that, but it could be a side-effect of it being parsed instead of just being treated as a local file path (as e.g. cp would). On a side note, to avoid future bugs, you should lowercase your variable names to avoid accidentally overriding special shell variables or environment variables. –  geirha Mar 16 '12 at 7:47
    
@geirha The books I read on bash programming all said to use upper case for variables - that it was a convention. Having programmed in other languages, it took awhile to get used to. I suppose someone will have to look at rsync source code to get the real answer, but I'm not sure I could figure it out. –  Joe Mar 21 '12 at 5:02

Your case is so simple, you could just remove the quotes around the variable:

rsync $DRYRUN -avushi --stats --progress --log-file="${LOGFILE2}" /media/dataspace"${DESTDIR2}"/ "${MOUNT}${DESTDIR2}"

But you may need the quotes in another case, in exemple if the parameter is a path containing spaces, which may or may not be defined. So, here is a more elegant solution:

linkdest="<OLD_BACKUP_PATH>"
rsync ${linkdest:+--linkdest="$linkdest"} -avushi --stats --progress --log-file="${LOGFILE2}" /media/dataspace"${DESTDIR2}"/ "${MOUNT}${DESTDIR2}"

If $linkdest is empty, nothing will be inserted. If $linkdest is not empty, --linkdest="$linkdest" will be inserted (and it will be evaluated as a command and not as a string).

share|improve this answer
    
+1 for the useful coding method. You're right that I could have just eliminated the quotes - but only after I knew that that was the problem. The point that I wanted to leave readers with is that if you accidentally provide rsync with a null parameter like I did, it causes unexpected behavior. Apparently, several other Linux shell commands do the same thing. –  Joe Aug 23 at 22:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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