尝试创建远程登录工具:"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
这个脚本的用例是我有不同的服务器和不同的 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