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