我如何 运行 期望脚本在服务器中通过 SSH 并在 bash 脚本中设置值
How can I run an expect script to SSH in a server and set a value inside a bash script
我有点晕。我有一些我可以访问的服务器,它们在服务器上有一个 BMC(底板管理控制器),但只有当你已经在接口上通过 SSHd 连接到服务器时(通过原样的数据路径)才能访问它。这个 BMC 有一个迷你 OS,但是这个 OS 上的日期完全不对,通常是一个月或更长时间,并且无法访问外部网络资源(除非你 scp 它们)它需要据我所知手动设置。我正在尝试编写一个 bash 脚本以通过 SSH 连接到服务器并获取当前日期(这是正确的),然后使用 expect 使用已知密码通过 SSH 连接到 BMC 并根据服务器设置日期已设置,但它只是 运行 脚本并退出并且不会更改它。更困难的部分是有时会有 2 个 expect 提示(一个是你真的想连接吗(yes/no),另一个是密码)。我四处搜寻,发现它们不是我为这个复杂问题找到的答案。此外,我有点新意,运行在 bash 脚本中设置它很困难。我能得到一些帮助吗?
我曾尝试在 bash 脚本中使用 EOD 将一部分 expect 调用到 运行,但没有成功。我也尝试使用我当前的代码:
期望-c "spawn ssh root@address "date -s $DATE"
预计 {
"(yes/no)"}
发送 -- "yes\r"
}
"My_known_PW"
}
但结果相同
#!/bin/bash
ssh root@ -oConnectTimeout=2 << "EOF"
PW="Known_PW"
DATE=$(date +"%y%m%d%H%M")
expect -c "
spawn ssh root@fe80::ff:feff:1%usb0 "date -s $DATE"
expect {
"(yes/no)" {
send -- "yes\r"
}
"$PW"
}
EOF
预期结果:SSH 到输入的服务器,获取 YYMMDDHHMM 格式的当前日期(即 1908031250)并设置为变量 DATE。然后通过 SSH 连接到 BMC 并从 $DATE 设置日期并退出。它所做的只是退出
您可能会看到 您真的要连接吗(yes/no)
- 这台机器是新的,以前从未连接过
- 机器签名已从白名单中手动删除(authorized_keys)。
- 以前的 SSH 命令有严格的说明,不在授权机器列表中记录机器签名。
以上任何一项都会提示 SSH 发出此警告。
您可以在 ~/.ssh/authorized_keys
文件中找到所有列入白名单的 IP 及其主机签名。
如果您信任远程机器,您可以指示 SSH 认为该机器是可信的,而不考虑机器签名。
这可以通过将 -o StrictHostKeyChecking=no
添加到 SSH 命令来完成。
ssh -o StrictHostKeyChecking=no root@fe80::ff:feff:1%usb0
You may wish to use a NTPd server for time synchronization. It looks like a long-winded way to achieve this at the moment.
想通了!我基本上不得不使用 "expect eof" 因为如果我理解正确的话,它有助于确保终端在执行命令之前准备就绪。代码现在显示为:
#!/bin/bash
if [[ $(ssh root@ -oBatchMode=yes -oConnectTimeout=2 -oLogLevel=QUIET "exit") ]];then
USER=root
else
USER=siteops
fi
ssh $USER@ -qoConnectTimeout=2 << "EOF"
DATE=$(date +"%y%m%d%H%M")
$(type -P expect) << EOD
spawn ssh root@fe80::ff:ff80:1%usb0 -o StrictHostKeyChecking=no "date -s $DATE"
expect "password:"
send "my_password\r"
expect eof
EOD
EOF
exit
expect is built atop tcl 这是一种功能齐全的脚本语言,内置了日期时间工具。您不需要在此处将 shell 变量传递到期望主体中:
ssh $USER@ -qoConnectTimeout=2 << "EOF"
$(type -P expect) << 'EOD'
set date [clock format [clock seconds] -format "%y%m%d%H%M"]
spawn ssh root@fe80::ff:ff80:1%usb0 -o StrictHostKeyChecking=no "date -s $date"
expect "password:"
send "my_password\r"
expect eof
EOD
EOF
我有点晕。我有一些我可以访问的服务器,它们在服务器上有一个 BMC(底板管理控制器),但只有当你已经在接口上通过 SSHd 连接到服务器时(通过原样的数据路径)才能访问它。这个 BMC 有一个迷你 OS,但是这个 OS 上的日期完全不对,通常是一个月或更长时间,并且无法访问外部网络资源(除非你 scp 它们)它需要据我所知手动设置。我正在尝试编写一个 bash 脚本以通过 SSH 连接到服务器并获取当前日期(这是正确的),然后使用 expect 使用已知密码通过 SSH 连接到 BMC 并根据服务器设置日期已设置,但它只是 运行 脚本并退出并且不会更改它。更困难的部分是有时会有 2 个 expect 提示(一个是你真的想连接吗(yes/no),另一个是密码)。我四处搜寻,发现它们不是我为这个复杂问题找到的答案。此外,我有点新意,运行在 bash 脚本中设置它很困难。我能得到一些帮助吗?
我曾尝试在 bash 脚本中使用 EOD 将一部分 expect 调用到 运行,但没有成功。我也尝试使用我当前的代码: 期望-c "spawn ssh root@address "date -s $DATE" 预计 { "(yes/no)"} 发送 -- "yes\r" } "My_known_PW" } 但结果相同
#!/bin/bash
ssh root@ -oConnectTimeout=2 << "EOF"
PW="Known_PW"
DATE=$(date +"%y%m%d%H%M")
expect -c "
spawn ssh root@fe80::ff:feff:1%usb0 "date -s $DATE"
expect {
"(yes/no)" {
send -- "yes\r"
}
"$PW"
}
EOF
预期结果:SSH 到输入的服务器,获取 YYMMDDHHMM 格式的当前日期(即 1908031250)并设置为变量 DATE。然后通过 SSH 连接到 BMC 并从 $DATE 设置日期并退出。它所做的只是退出
您可能会看到 您真的要连接吗(yes/no)
- 这台机器是新的,以前从未连接过
- 机器签名已从白名单中手动删除(authorized_keys)。
- 以前的 SSH 命令有严格的说明,不在授权机器列表中记录机器签名。
以上任何一项都会提示 SSH 发出此警告。
您可以在 ~/.ssh/authorized_keys
文件中找到所有列入白名单的 IP 及其主机签名。
如果您信任远程机器,您可以指示 SSH 认为该机器是可信的,而不考虑机器签名。
这可以通过将 -o StrictHostKeyChecking=no
添加到 SSH 命令来完成。
ssh -o StrictHostKeyChecking=no root@fe80::ff:feff:1%usb0
You may wish to use a NTPd server for time synchronization. It looks like a long-winded way to achieve this at the moment.
想通了!我基本上不得不使用 "expect eof" 因为如果我理解正确的话,它有助于确保终端在执行命令之前准备就绪。代码现在显示为:
#!/bin/bash
if [[ $(ssh root@ -oBatchMode=yes -oConnectTimeout=2 -oLogLevel=QUIET "exit") ]];then
USER=root
else
USER=siteops
fi
ssh $USER@ -qoConnectTimeout=2 << "EOF"
DATE=$(date +"%y%m%d%H%M")
$(type -P expect) << EOD
spawn ssh root@fe80::ff:ff80:1%usb0 -o StrictHostKeyChecking=no "date -s $DATE"
expect "password:"
send "my_password\r"
expect eof
EOD
EOF
exit
expect is built atop tcl 这是一种功能齐全的脚本语言,内置了日期时间工具。您不需要在此处将 shell 变量传递到期望主体中:
ssh $USER@ -qoConnectTimeout=2 << "EOF"
$(type -P expect) << 'EOD'
set date [clock format [clock seconds] -format "%y%m%d%H%M"]
spawn ssh root@fe80::ff:ff80:1%usb0 -o StrictHostKeyChecking=no "date -s $date"
expect "password:"
send "my_password\r"
expect eof
EOD
EOF