尝试创建远程登录工具:"expect << EOF" 中的 "interact" 不起作用

Trying to Create a remote login tool: "interact" in "expect << EOF" does not work

这个脚本的用例是我有不同的服务器和不同的 ssh 密钥。我正在尝试编写一个脚本,以便在调用时登录到指定的服务器。一个用法示例是:

    ./ServerLogin.sh Server1

我觉得我已经很接近了,但是expect interact的最后一部分让我绊倒了。这是一个简化版本:

#!/bin/bash

ServerName=""
case $ServerName in 
  "Server1") IP="1.2.3.4" ; keyPath="/path/to/key.pem" ; password="password" ; break ;;
  *)         echo "Server not recognized" ; exit ;;
esac 

/usr/bin/expect << EOD
spawn ssh -i $keyPath user@$IP
expect "*.pem': "
send "$password\r"
interact
EOD

这样做的结果是登录并立即关闭。我希望会话保持可交互性。

有什么想法吗?

在反复尝试之后,我找到了一个可行的解决方案。基本上创建 expect 脚本和 运行 它。为什么它这样工作而不是在最初的问题中是超出我的范围。但它有效,我将暂时使用它。谢谢大家的帮助!

工作解决方案:

#!/bin/bash

ServerName=""
case $ServerName in 
  "Server1") IP="1.2.3.4" ; keyPath="/path/to/key.pem" ; password="password" ; break ;;
  *)         echo "Server not recognized" ; exit ;;
esac 

function WriteExp {
  echo "#!/usr/bin/expect"
  echo "spawn ssh -i $keyPath ubuntu@$IP"
  echo "expect \"*.pem': \""
  echo "send \"$password\r\""
  echo "interact"
}

WriteExp > $ServerName.exp
chmod 755 $ServerName.exp

/usr/bin/expect $ServerName.exp

# Cleanup the evidence
rm $ServerName.exp

问题出在expect << EOF。对于 expect << EOF,expect 的标准输入是 here-doc 而不是 tty。但是 interact 命令只有在 expect 的标准输入是 tty 时才有效。您的答案是一种解决方案。如果您不想使用 tmp 文件,另一种解决方案是使用 expect -c

expect -c "
  spawn ssh -i $keyPath user@$IP
  expect \"*.pem': \"
  send \"$password\r\"
  interact
"

仅使用 tcl/expect,而不是 shell 的混合,代码更简洁,没有任何由 shell 变量插值引起的潜在问题:

#!/usr/bin/expect -f

switch -- [lindex $argv 0] {
    Server1 { 
       set IP 1.2.3.4
       set keyPath /path/to/key.pem
       set password "password"
    }
    default {
       puts stderr "Server not recognized"
       exit 1
    }
}

spawn ssh -i $keyPath user@$IP
expect "*.pem': "
send "$password\r"
interact