35

I am trying to write a simple bash script for my local (Mac OS X) machine to move files from a directory on my machine to a remote machine. This line is failing:

rsync --verbose  --progress --stats --compress --rsh=ssh \
      --recursive --times --perms --links --delete \
      --exclude "*bak" --exclude "*~" \
      /repository/* $DEV_SERVER:$REMOTE_DIR

$DEV_SERVER and $REMOTE_DIR are defined previously, and I echo them to verify they're accurate.

The error I'm getting is:

rsync: link_stat /Users/myusername/mycurrentdirectory failed: No such file or directory (2)

To note here is that rather than using the defined directory (/repository, which is in the root of the machine), it uses my working directory. What is causing this?

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102

5 Answers5

52

Check that your \ characters have no whitespace after them at the end of the line. This will cause BASH to not interpret the line wrap correctly, giving the rsync error above.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
Martin Smith
  • 544
  • 5
  • 3
  • In my case, this error occured when the rsync -e option was supplied with an empty string or a space char AND the target file (to be synced with) did not already exist. (The -e option value was being determined conditionally). – Snidhi Sofpro Oct 23 '20 at 07:53
12

Remove the '*' from the source location, rsync knows to look in the inside of the directory if you specify the '/' in the end

like that:

rsync --verbose  --progress --stats --compress --rsh=ssh --recursive --times --perms --links --delete --exclude "*bak" --exclude "*~" /repository/ $DEV_SERVER:$REMOTE_DIR
Garry Gerber
  • 196
  • 1
  • 6
2

I was encountering the same error while doing some rsync work. I had the wrong character for specifying options which I must have gotten from copying and pasting the command from elsewhere:

rather than the correct character below:

-
Paul
  • 7,155
  • 8
  • 41
  • 40
  • thanks, that was a subtle one! Ran into exactly this when copy-pasting rsync arguments from various websites. – timotgl Feb 11 '22 at 12:01
0

The source path (here: /repository/*) does contain a wildcard (*). There is some info in the man pages for rsync: "Note that the expansion of wildcards on the commandline (*.c) into a list of files is handled by the shell before it runs rsync and not by rsync itself (exactly the same as all other posix-style programs)."

I.e. in case you put in bash double quotes "" around the (source path) including the wildcard symbol (*), the rsync commandwill succeed on command line interface, while inside a bash shell it will yield exactly the error described here.

rsync: link_stat "<source path>*" failed: No such file or directory (2)

=> make sure to not put the wild card(s) in quotes in an rsync source path.

Beth Long
  • 375
  • 3
  • 24
  • I have `"rsync -r --exclude {'*.root','*tmp/','*.mac','SomeString*'} ~/mypath"` - I've tried swapping the single and double quotes but it gives me this error for `//*tmp`, `*.mac` and `BhabhaSCh*` in both cases. Any ideas? – Beth Long Dec 06 '22 at 19:51
  • Hi Beth, First, I do miss the in your command sample, and assume an * is missing. Second, there may be an equal sign '=' required for --exclude={ 'pattern1', 'pattern2', ..., 'patternN' }. Then ultimately bash will quasi "remove" the quotes, single or double, which is why the exclude list will not work as expected (even if you add the equal sign '='). Still, you can use --exclude multiple times without single quotes: "rsync -r --exclude *.root --exclude *tmp/ --exclude *.mac --exclude SomeString* ~/mypath" This should work. – Volker Fröhlich Dec 08 '22 at 14:43
  • You're right about the `sourcepath` - in my command I have it, but I didn't copy it here. Anyway, this still isn't working: `rsync -r --exclude *.root --exclude *tmp/ --exclude *.mac --exclude SomeString* ~/mydir/ /targetpath`, all the files I wanted to exclude are still being copied... – Beth Long Dec 08 '22 at 15:39
  • Beth, you are right and obviously the single quotes are necessary for --exclude. In order to reproduce your issue, I just created a bash script and to my surprise the single quotes do work there. the script executes just as expected, excluding files and directories which were identified with a pattern containing an asterisk. just as a side note - I always use the -a instead of r - but this should not be the root cause for the difference. Here's the script I executed: #!/bin/sh rsync -a --exclude '*.txt' --exclude '*xxx/' * ~/tmp – Volker Fröhlich Dec 08 '22 at 17:51
  • This now excludes `*.root` and `*.mac` files but not `SomeString*` files or everything that ends in `*~` which I requested it to do – Beth Long Dec 08 '22 at 19:28
-1

This:

rsync --verbose  --progress --stats --compress --rsh=ssh \
  --recursive --times --perms --links --delete \
  --exclude "*bak" --exclude "*~" \
  /repository/* $DEV_SERVER:$REMOTE_DIR

should be this:

rsync --verbose  --progress --stats --compress --rsh=ssh --recursive --times --perms --links --delete --exclude "*bak" --exclude "*~" /repository/* $DEV_SERVER:$REMOTE_DIR

Bash interprets the \ character differently than the command line, or perhaps there is an implicit non-whitespace character after it.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • How does bash handle it differently in non-interactive sessions? – jordanm May 23 '12 at 20:13
  • Better suited for superuser.com – Gilles Quénot May 23 '12 at 20:19
  • 3
    The only problem I've had with using the line-continuation-char (i.e. `\`), on cmd-line OR in a script, is when there is any character besides a `\n` character after it. I didn't downvote your answer, but I don't think it's right. Good luck to all. – shellter May 23 '12 at 20:55
  • 3
    This is plain wrong. Bash interprets a script exactly the same way as it interprets input from the command prompt. – holgero Feb 02 '13 at 15:17
  • There's not difference in the syntax for interactive and non-interactive shell. – nishantjr Jan 17 '15 at 07:32