expect 脚本中的 Rsync:错误“没有这样的文件或目录”

问题描述 投票:0回答:2

我想执行 rsync 来更新另一台计算机上的多个目录,而不需要为每个目录输入密码。我决定通过一些简单的 StackOverflow 示例来尝试 Expect 扩展。请参阅下面我的脚本的非常简化的版本。 rsync 命令单独执行时可以正常工作。但是,当我运行脚本时,我得到以下输出:

Remote password: 
spawn rsync -rv /home/john/TestDir/* [email protected]:/home/jim/TestDir
([email protected]) Password:
building file list ... 
rsync: [sender] link_stat "/home/john/TestDir/*" failed: No such file or directory (2)
done

sent 17 bytes  received 20 bytes  74.00 bytes/sec
total size is 0  speedup is 0.00
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1338) [sender=3.2.7]
#!/usr/bin/expect -d
 
read -s -p "Remote password: " PW
echo ""
expect <<EOF
    spawn rsync -rv  /home/john/TestDir/* [email protected]:/home/jim/TestDir
    expect "assword:"
    send "$PW\r"
    expect eof
EOF

expect
2个回答
0
投票

问题是,当您在 shell 中输入

/path/*
时,shell 会将此模式扩展为文件名列表,然后将其作为参数传递。但是,
spawn
expect
命令不会进行模式扩展,因此 rsync 接收到文字
*
,并且该名称的文件不存在。

有多种方法可以解决这个问题。一是更改命令以不使用模式扩展。 @pynexj 建议删除

*
,这是可行的,但请注意,
rsync -r foo/* bar
rsync -r foo/ bar
之间存在差异:后者也会复制隐藏文件(以
.
开头),而前者则不会(因为它们与
*
不匹配)。

但是,您说您的目标是复制多个目录,而无需为每个目录输入密码。实现此目的的更好解决方案可能是设置公钥身份验证,因此您根本不必输入任何密码。

这是有关如何配置此功能的教程:https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server


0
投票

对于 Expect (使用

*
中的
/home/john/TestDir/*
字符没有特殊含义。您可以显式使用 shell 来运行命令:

spawn bash -c "rsync -rv  /home/john/TestDir/* [email protected]:/home/jim/TestDir"
#     ^^^^^^^
© www.soinside.com 2019 - 2024. All rights reserved.