rsync错误:使用包含“*”字符的源时

时间:2012-01-02 11:02:29

标签: tcl rsync

在我的TCL脚本中,我使用rsync命令,不幸的是它拒绝同步路径包含“*”字符。

代码示例:

 set srs "/users/home/username/common/*"
 catch {exec  rsync -av $src /tmp} res
 puts $res

输出:

 building file list ... done

 sent 29 bytes  received 20 bytes  98.00 bytes/sec
 total size is 0  speedup is 0.00
 rsync: link_stat "/users/home/username/common/*" failed: No such file or directory (2)
 rsync error: some files could not be transferred (code 23) at main.c(977) [sender=2.6.9]
    while executing
  "exec  rsync -rLptgov  $src /tmp "

3 个答案:

答案 0 :(得分:1)

要详细说明GrAnd所说的内容,你必须明确地构建源文件列表,可能使用glob,所以你就这样做了

set cmd [concat [list exec rsync -av] \
                [glob -nocomplain /users/home/username/common/*]]
lappend cmd /tmp
catch {eval $cmd} res
puts $res

或者,使用{*}扩展exec的agument列表(这是针对Tcl> = 8.5),如下所示:

set cmd [concat [list rsync -av] \
                [glob -nocomplain /users/home/username/common/*]]
lappend cmd /tmp
catch {exec {*}$cmd} res
puts $res

更新:修复了示例,以便它确实有效。

答案 1 :(得分:1)

规范的写作方式是:

set srs "/users/home/username/common/*"
catch {exec rsync -av {*}[glob $src] /tmp} res
puts $res

这是因为默认情况下Tcl不会扩展glob元字符;这样更安全,更容易编写正确的代码(它是 hard 编写能够抵抗这方面问题的优秀shell代码),但它确实意味着你需要做一些额外的工作。额外的工作是:

  1. 使用$srs命令询问glob的全局扩展。这会返回一个列表。
  2. 通过使用glob伪运算符(它不是运算符 - 从技术上讲它是一种语法 - 请求从{*}扩展列表 - 但它的工作原理很像一个)。

  3. 如果您正在使用Tcl 8.4(或之前!),那么您可以采用不同的方式:

    set srs "/users/home/username/common/*"
    catch {eval [list exec rsync -av] [glob $src] [list /tmp]} res
    puts $res
    

    好吧,有时通常会忽略list位(并且还有更多不起眼的方式来编写它!)但这是一个坏习惯,因为它可能会导致巨大的问题处理具有非“好”值的变量时,例如,路径名中包含空格。如果您有8.5或更高版本,请使用{*}。真。

答案 2 :(得分:0)

那是因为tcl解释器没有扩展' *'像壳一样的符号。

例如:

$ tclsh
% cd /usr
% exec ls -d *
ls: *: No such file or directory
% exec sh -c "ls -d *"
X11R6
bin
docs
etc
...