Bash脚本rsync:rsync:link_stat(blah)失败:没有这个文件或目录(2)

36

我想为我的本地(Mac OS X)机器编写一个简单的bash脚本,将本地目录中的文件移动到远程机器。这一行代码出现了问题:

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

$DEV_SERVER$REMOTE_DIR已经被先前定义,我使用echo命令来验证它们的准确性。

我得到的错误是:

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

需要注意的是,它并没有使用所定义的目录(/repository,位于机器的根目录下),而是使用了我的工作目录。这是什么原因呢?


2
请使用引号引用变量! - Dennis Williamson
5个回答

54

检查您的\字符在行末是否没有空格。这将导致BASH无法正确解释换行符,从而产生上述rsync错误。


在我的情况下,当rsync -e选项提供了一个空字符串或空格字符,并且目标文件(要与之同步的文件)不存在时,就会出现此错误。(-e选项值是有条件确定的)。 - Snidhi Sofpro

13

如果你在源地址中去掉“*”符号,rsync会查找目录内部,如果你在结尾指定了“/”符号。

像这样:

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

2

在进行一些rsync工作时,我遇到了相同的错误。我使用了错误的字符来指定选项,这可能是我从其他地方复制和粘贴命令时获得的:

而不是下面正确的字符:

-

谢谢,这个问题比较微妙!从各种网站复制rsync参数时正好遇到了这个问题。 - timotgl

0

源路径(这里是/repository/*)包含通配符(*)。 在rsync的man页面中有一些信息: “请注意,命令行上通配符(*.c)的扩展成文件列表是由shell在运行rsync之前处理的,而不是由rsync本身处理的(与所有其他posix风格的程序完全相同)。"

也就是说,如果您在bash中双引号""中放入(源路径),包括通配符符号(*),则rsync命令将在命令行界面上成功执行,而在bash shell内部,则会产生与此处描述的错误完全相同的错误。

rsync:link_stat“<source path>*”失败:没有那个文件或目录(2)

=> 确保不要在rsync源路径中用引号括起来放置通配符。


我有这个命令:"rsync -r --exclude {'.root','tmp/','.mac','SomeString'} ~/mypath" - 我尝试交换单引号和双引号,但无论哪种情况下,它都会给我在//tmp、.mac和BhabhaSCh*处的错误。有什么想法吗? - Beth Long
嗨Beth, 首先,我在你的命令示例中错过了<sourcepattern>,并假设缺少一个*。 其次,--exclude={ 'pattern1','pattern2',...,'patternN' }可能需要一个等号'='。 然后最终bash将准“删除”引号,单引号或双引号,这就是为什么排除列表不起作用的原因(即使您添加等号'=')。不过,您仍然可以多次使用--exclude而不使用单引号: “rsync -r --exclude *.root --exclude *tmp/ --exclude .mac --exclude SomeString <sourcepattern> ~/mypath” 这应该可以工作。 - Volker Fröhlich
你关于 sourcepath 的说法是正确的 - 在我的命令中我有它,但我没有在这里复制。无论如何,这仍然不起作用:rsync -r --exclude *.root --exclude *tmp/ --exclude *.mac --exclude SomeString* ~/mydir/ /targetpath,我想要排除的所有文件仍然被复制了... - Beth Long
Beth,你是对的,显然单引号在--exclude中是必要的。 为了重现你的问题,我刚刚创建了一个bash脚本,令我惊讶的是单引号确实可以在那里工作。脚本执行得如预期一样,排除了包含星号模式的文件和目录。 只是顺便提一下 - 我总是使用-a而不是-r - 但这不应该是差异的根本原因。 这是我执行的脚本: #!/bin/sh rsync -a --exclude '*.txt' --exclude '*xxx/' * ~/tmp - Volker Fröhlich
Beth,你是对的,显然单引号在--exclude参数中是必要的。 为了重现你的问题,我刚刚创建了一个bash脚本,令人惊讶的是,单引号确实在那里起作用。脚本按预期执行,排除了包含星号模式的文件和目录。 只是顺便提一下 - 我总是使用-a而不是-r - 但这不应该是差异的根本原因。 这是我执行的脚本: #!/bin/sh rsync -a --exclude '*.txt' --exclude '*xxx/' * ~/tmp - Volker Fröhlich
现在排除了 *.root*.mac 文件,但不包括 SomeString* 文件或以 *~ 结尾的所有文件,这是我要求它做的。 - Beth Long

-1

这个:

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

应该是这样的:

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

Bash解释\字符与命令行不同,或者它后面有一个隐含的非空格字符。


Bash在非交互式会话中如何处理它的不同之处? - jordanm
更适合于superuser.com。 - Gilles Quénot
3
我在使用行继续字符(即\)时遇到的唯一问题是,在它之后存在除\n字符以外的任何字符时,无论是在命令行还是脚本中。我没有对你的回答进行投票,但我认为它不正确。祝大家好运。 - shellter
3
这是完全错误的。Bash 解释脚本的方式与解释来自命令提示符的输入完全相同。 - holgero
交互式和非交互式 shell 的语法没有区别。 - nishantjr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接