我正在使用 SSH 更改远程计算机上的一些配置设置。要应用这些配置,我需要重新启动。之后,我需要再次重新连接以进行更多配置更改。例如:
#!/bin/bash
ssh <host> 'sh -s' < first-step.sh
# Wait for system to reboot...
rebooted=false
while [[ "$rebooted" = false ]]; do
...
done
ssh <host> 'sh -s' < second-step.sh
...
我的问题是:我应该检查什么条件才能设置
rebooted=true
?我的想法是尝试通过 ssh
连接,直到命令不再返回错误(在尝试之间使用 sleep
进行连接),但这似乎相当初级。也许可以从远程计算机发送一条“我已重新启动”类型的消息并让本地计算机监听该消息?
Linux 内核生成一个唯一的随机标识符来反映每次系统启动。 (这有实际用途:例如,可以向日志请求特定启动会话期间生成的日志;因此您可能希望记录或保留它)。
在发出重新启动命令之前收集
/proc/sys/kernel/random/boot_id
的内容。
仅当它更改为不同的非空值时,才认为重新启动已完成。
因此,最终可能会得到如下所示的代码:
#!/usr/bin/env bash
{
initial_boot_id=$(ssh somehost 'cat /proc/sys/kernel/random/boot_id') &&
[[ $initial_boot_id ]]
} || { echo 'Unable to collect initial boot id' >&2; exit 1; }
ssh somehost reboot
ok=0
while (( i=0; i<=30; i++ )); do
if final_boot_id=$(ssh somehost 'cat /proc/sys/kernel/random/boot_id') &&
[[ $final_boot_id ]] &&
[[ $final_boot_id != "$initial_boot_id" ]]; then
echo "Reboot complete" >&2
ok=1
break
fi
done
if (( ! ok )); then
echo "ERROR: Successful reboot not detected" >&2
exit 1
fi
echo "System successfully rebooted" >&2
echo "${initial_boot_id} => ${final_boot_id}" >&2
exit 0
(请注意,上面使用了 bashisms——因此使用
#!/usr/bin/env bash
shebang 而不是 #!/bin/sh
)。
以下内容是基于两个假设编写的:
cron
版本支持 @reboot
选项。您只需添加到用户的
crontab
即可 ssh
返回原始计算机:
@reboot <uptime -s >> ssh origin_host 'cat >> /var/log/last_time_machine_x_rebooted'
用于将本地命令的输出获取到远程服务器的方法取自 Unix Stackexchange 上的这个答案。
还有一个基于
scp
的选项,看起来像:
@reboot uptime -s >> /var/log/last_time_machine_x_rebooted && scp /var/log/last_time_machine_x_rebooted origin_host:/var/log/last_time_machine_x_rebooted