Tcl expect脚本中的rsync路径
我编写了一个备份脚本,它使用Tcl expect脚本中的rsync路径,tcl,expect,rsync,Tcl,Expect,Rsync,我编写了一个备份脚本,它使用expect自动执行rsync 为了确保备份所有文件,我使用了rsync的选项 我已经看到了在rsync命令行中使用空格的方法,并在这里和那里添加了单引号、双引号和转义反斜杠,但还没有任何效果 如何使“--rsync path带空格”在expect脚本中工作?您不能使用--rsync path来实现这一点,因为您需要的是分词,即shell所做的事情 那么,如何通过指定单个路径名来运行运行命令的命令呢 在远程系统上,编写脚本包装器susync执行sudo(不要忘记chm
expect
自动执行rsync
为了确保备份所有文件,我使用了rsync
的选项
我已经看到了在rsync
命令行中使用空格的方法,并在这里和那里添加了单引号、双引号和转义反斜杠,但还没有任何效果
如何使“--rsync path
带空格”在expect
脚本中工作?您不能使用--rsync path
来实现这一点,因为您需要的是分词,即shell所做的事情
那么,如何通过指定单个路径名来运行运行命令的命令呢
在远程系统上,编写脚本包装器susync
执行sudo
(不要忘记chmod 755
):
和使用
spawn rsync --rsync-path=/path/to/susync ...
问题是你有这样的问题:
--rsync-path="sudo\\ rsync"
在Expect/Tcl中,这被视为:
--rsync-path="sudo rsync"
而且,由于Tcl的引用规则与bash的不同,因此它使用带有双引号的“sudo rsync”
作为发送到远程端的命令。这让事情变得非常混乱。正确的解决方法是省略双引号;(反斜杠引号)反斜杠将确保它作为一个参数进入spawn,并正确地发送到另一端
我真的不喜欢在Tcl中使用HEREdocs。当不同类型的引用相互作用时,太多的事情会变得怪异。最好在真正的目标语言中使用单个脚本,因为这样可以使用变量使事情更清楚:
#!/usr/bin/env expect
set remoteRsync "sudo rsync"
set from myuser@example.com:/home/myuser/
set to /backups/home/myuser
set pass "mypassword"
spawn rsync --rsync-path=$remoteRsync -uav $from $to
expect ":"
send -- "$pass\r"
expect eof
exit
这使得代码的结构更易于查看,也更易于调试。开头带有/usr/bin/env
的位只是一种避免使用bash包装器的方法
不,这些变量在使用时不需要引用。Tcl不是bash。您为什么不
生成sudo rsync…
?@Jens,是的,不使用生成sudo rsync…
,有两个原因:rsync
应该在远程系统上以sudo权限运行。。。2.我的本地计算机没有sudo
。您不能使用--rsync path来执行此操作,因为您需要的是分词,即shell所做的事情。。那我怎么能运行rsync--rsync path=“sudo\\rsync”-uav呢myuser@example.com:/home/myuser//backups/home/myuser
直接在我的本地bash shell上成功吗?遥控器也使用bash shell。@Abdull可能是因为作为客户端,rsync使用system(“x”)
,但在服务器上它使用exec(“x”)
。第一个调用shell,第二个直接执行x。这都是猜测。在我(非常特殊)的情况下,这种变通方法比调试shell正在进行的疯狂字符串操作更容易。感谢JensAwesome,使用Tcl的set
为变量赋值解决了我的问题。通过转义所有Tcl变量引用(例如,$from
变为\$from
),我仍然可以使用heredocument方法。
--rsync-path="sudo\\ rsync"
--rsync-path="sudo rsync"
#!/usr/bin/env expect
set remoteRsync "sudo rsync"
set from myuser@example.com:/home/myuser/
set to /backups/home/myuser
set pass "mypassword"
spawn rsync --rsync-path=$remoteRsync -uav $from $to
expect ":"
send -- "$pass\r"
expect eof
exit