我想创建一个 shell 脚本来重新启动 Linux 机器,这样当机器重新启动并运行时脚本就会结束(启动并运行的意思是接受 ssh 连接)。
该脚本的执行方式如下(伪代码):
reboot machine #sth like 'ssh root@MACHINE reboot'
respecting a timeout of 120 secods do:
try to connect to machine by ssh
sleep one second if it could not connect
return an error if timed out
return ok if machine is ready for ssh connections
事实是,我真的想避免长时间的睡眠命令,以便我的重启脚本尽快给出结果(当然,如果不是超时的话)。
有人做过类似的事情吗?
更新:从 adamo 的想法开始我做了:
timeout=120
start=$(date +%s)
ssh root@$FAST_HOST reboot
do
nc -z $1 22
if [ $? eq 0]; then
echo host is ready
exit 0
fi
end=$(date +%s)
diff=$(( $end - $start ))
if [ $diff -gt timeout ]
echo timeout
exit 1
fi
sleep 1
done
我的问题是,当无法连接时,nc 命令需要很长时间才能返回。有没有办法在很短的超时时间内检查端口是否打开?
答案1
我使用类似下面的方法在重启时连接机器。它要求您设置公钥身份验证(或其他无密码身份验证)。
#!/bin/sh
if [ -z "$1" ] ; then
echo "You must pass a host to reboot."
fi
HOST="$1"
USER="USER TO SSH AS"
# if the user has the right to reboot a machine without sudo,
# the following can be empty.
SUDO="/usr/bin/sudo"
SSH="/usr/bin/ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=1 $USER@$HOST"
echo -n "Rebooting $HOST..."
if ! $SSH $SUDO reboot ; then
echo 'FAILED!'
exit 1
fi
echo "ok."
echo -n "Sleeping 30 seconds..."
sleep 30
echo "done."
echo -n "Waiting for $HOST..."
while ! $SSH echo -n > /dev/null 2>/dev/null ; do
echo -n '.'
done
echo "ok."
echo "Machine rebooted successfully."
答案2
尝试这样的操作:
#!/bin/bash
sleep 120
while true
do
nc -z $1 22
if [ $? eq 0 ]; then
echo host is ready
exit 0
fi
sleep 1
done
您需要完善它(例如检查是否向脚本提供了参数等等......)
答案3
尝试使用它。如果需要,nmap -p 22
它可以与选项集结合使用。--*-rtt-timeout
另一方面,尝试完全不同的方法(如 SNMP)怎么样?它似乎更接近您的需要,并且解决了您在尝试重新发明轮子时遇到的许多问题……
答案4
您可以在循环内使用 ping,其超时时间与您在上面的问题中介绍的类似。
您可以一次执行一次 ping,然后检查其退出状态。成功 ping 后(退出状态为 0),您可以检查 SSH。
编辑:
另一种方法是,您可以让远程计算机在启用 SSH 的情况下启动并运行时通知您。例如,您可以添加这样的命令,在系统启动期间执行。它可以添加到 SSH 守护程序启动文件中。
scp /root/dummy_file root@your_machine:~
当然,这应该在两台机器(从远程机器到监控机器)之间建立信任之后完成,以避免要求输入密码。
在监控机器上,如果脚本开头存在该文件,则可以删除该文件。重新启动后,可以检查该文件。如果该文件存在,则机器将重新启动并运行。