如何通过SSH捕获远程Linux机器启动日志并验证重启状态?
Python远程Linux重启脚本:捕获启动日志与验证重启状态问题解答
问题背景
目标:编写Python测试脚本,通过SSH对远程Linux机器执行重启命令,捕获启动日志并验证重启是否成功。
当前问题:使用Paramiko发送重启命令后机器可正常重启,但无法捕获启动日志,且代码未等待重启完成就执行完毕。
原代码片段
import paramiko import time ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: ssh.connect(host, username=username, password=password) except paramiko.SSHException as e: ssh.get_transport().auth_none(username) # 无密码认证 # 执行重启命令并捕获启动日志 stdin, stdout, stderr = ssh.exec_command("/sbin/reboot") print(stdout.readlines()) print(stderr.readlines()) # 检查重启是否完成 exit_status = '' msg = '' while True: if stdout_channel.exit_status_ready(): exit_status = ssh.stdout.channel.recv_exit_status() print("Exit status: %s" % exit_status) break time.sleep(10) ssh.close() if exit_status == 0: print("Reboot successful") else: print("Reboot not successful")
执行输出
[] [] Exit status: 0 Reboot successful
问题解答
a) 如何捕获启动日志?
原代码无法捕获启动日志的核心原因:reboot命令执行后会立即返回退出状态码,SSH会话随即断开,而系统启动日志是在重启过程中产生的,无法通过当前SSH会话获取。
可行解决方案:
- 步骤1:确保目标机器启动日志持久化
大部分Linux系统默认会将启动日志保存到/var/log/boot.log,或通过systemd-journald持久化存储日志(可通过journalctl命令查看)。如果目标机器未开启日志持久化,可提前配置(比如修改rsyslog或journald配置)。 - 步骤2:重启后重新连接读取日志
待机器重启完成并恢复SSH服务后,重新建立SSH连接,执行日志读取命令:- 读取传统启动日志文件:
cat /var/log/boot.log - 读取systemd启动日志:
journalctl -b(-b表示查看本次启动的日志)
- 读取传统启动日志文件:
b) 如何正确检查重启完成后的状态?
原代码通过reboot命令的退出状态判断重启成功是错误的——reboot命令只要发送成功就会返回0,和机器是否完成重启无关。正确的验证逻辑如下:
- 发送重启命令后主动断开SSH连接
执行reboot后,当前SSH会话会很快失效,无需等待,直接关闭连接。 - 循环尝试重新连接目标机器
机器重启过程中SSH服务会中断,需要循环尝试连接,直到连接成功(说明机器已重启完成并恢复SSH服务)。 - 连接成功后验证重启状态
可执行以下命令验证:who -b:查看系统最后启动时间,确认是本次重启的时间uptime:查看系统运行时长,确认时长较短(刚重启)- 检查关键服务状态(如
systemctl status <service-name>)
修改后的完整代码示例
import paramiko import time def ssh_connect(host, username, password=None): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: if password: ssh.connect(host, username=username, password=password, timeout=10) else: ssh.connect(host, username=username, timeout=10) return ssh except (paramiko.SSHException, TimeoutError): return None def main(): host = "your-remote-host" username = "your-username" password = "your-password" # 无密码则设为None # 第一步:建立连接并发送重启命令 ssh = ssh_connect(host, username, password) if not ssh: print("初始SSH连接失败") return print("发送重启命令...") stdin, stdout, stderr = ssh.exec_command("/sbin/reboot &") # 立即关闭连接,因为重启后会话会失效 ssh.close() # 第二步:等待机器重启并尝试重新连接 print("等待机器重启...") reconnect_attempts = 12 # 最多尝试12次,每次间隔10秒,共2分钟 connected = False while reconnect_attempts > 0: time.sleep(10) ssh = ssh_connect(host, username, password) if ssh: connected = True break reconnect_attempts -= 1 print(f"重新连接失败,剩余尝试次数:{reconnect_attempts}") if not connected: print("机器重启后无法重新连接,验证失败") return # 第三步:验证重启状态 print("验证重启状态...") # 检查最后启动时间 stdin, stdout, stderr = ssh.exec_command("who -b") boot_time = stdout.read().decode().strip() print(f"系统最后启动时间:{boot_time}") # 读取启动日志 print("读取启动日志:") stdin, stdout, stderr = ssh.exec_command("journalctl -b --no-pager | head -50") # 取前50行示例 boot_log = stdout.read().decode() print(boot_log) # 检查系统运行时长 stdin, stdout, stderr = ssh.exec_command("uptime") uptime_info = stdout.read().decode().strip() print(f"系统运行时长:{uptime_info}") ssh.close() print("重启验证完成,机器已成功重启") if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者Michael Tan
相关产品推荐
相关产品推荐

