如何让expect正确嵌套在bash脚本中?

How to make expect nested in the bash script properly?

这是可以运行成功的预期文件。

#!/usr/bin/expect  -f
set host vps_ip
set user test
set loginpwd  passwd
set adminpwd  passwd
set timeout 300
set prompt "#|>|\$"    
spawn scp  /home/wpdatabase_backup.sql   $user@$host:/tmp
expect -nocase  "password:"
send "$loginpwd\r"
expect eof
spawn  ssh  $user@$host
expect -nocase "password:"
send "$loginpwd\r"
expect -re $prompt
send "su\r"
expect  "assword:"
send "$adminpwd\r"
expect -re $prompt
send "mysql -u root -pxxxx wpdatabase < /tmp/wpdatabase_backup.sql\r"
expect eof

这是 bash 文件:

mysqlword="xxxx"
mysqldump -u root -p$mysqlword wpdatabase > /home/wpdatabase_backup.sql

现在我想将expect文件嵌套在bash文件中,因为bash文件比expect文件更复杂,bash文件中的大部分行都被省略了。

代码:

#!/usr/bin/bash
mysqlword="xxxx"
mysqldump -u root -p$mysqlword wpdatabase > /home/wpdatabase_backup.sql    
/usr/bin/expect <<EOD
set host vps_ip
set user test
set loginpwd  passwd
set adminpwd  passwd
set timeout 300
set prompt "#|>|\$"

spawn scp  /home/wpdatabase_backup.sql   $user@$host:/tmp
expect -nocase  "password:"
send "$loginpwd\r"
expect eof
spawn  ssh  $user@$host
expect -nocase "password:"
send "$loginpwd\r"
expect -re $prompt
send "su\r"
expect  "assword:"
send "$adminpwd\r"
expect -re $prompt
send "mysql -u root -pxxxx wpdatabase < /tmp/wpdatabase_backup.sql\r"
expect eof
<<EOD

发生错误: spawn scp /home/wpdatabase_backup.sql @:/tmp
ssh:无法解析主机名:名称或服务未知
失去联系
发送:spawn id exp6 未打开
执行时
"send "\r""

引用终结者:

cat<<'EOD'
set host vps_ip
set user test
spawn scp  /home/wpdatabase_backup.sql   $user@$host:/tmp
EOD

结果:

set host vps_ip
set user test
spawn scp  /home/wpdatabase_backup.sql   $user@$host:/tmp

但是如何在bash中输出结果运行?

/usr/bin/expect  <<cat<<'EOD'
set host vps_ip
set user test
spawn scp  /home/wpdatabase_backup.sql   $user@$host:/tmp
EOD

代码不能运行!

这是因为在像 EOD 这样带有不带引号的终止符的 here-document 中,参数替换是由 shell 执行的。你可以看到,如果将 /usr/bin/expect 替换为 cat:

$ cat<<EOD
set host vps_ip
set user test
spawn scp  /home/wpdatabase_backup.sql   $user@$host:/tmp
EOD

结果:

set host vps_ip
set user test
spawn scp  /home/wpdatabase_backup.sql   @:/tmp

那么,如何避免参数替换呢?引用终结者:

$ cat<<'EOD'
set host vps_ip
set user test
spawn scp  /home/wpdatabase_backup.sql   $user@$host:/tmp
EOD

结果:

set host vps_ip
set user test
spawn scp  /home/wpdatabase_backup.sql   $user@$host:/tmp