如何在不重新启动的情况下非破坏性地检查 grub2 是否已安装在引导扇区中或是否由 grub1 链式加载?

如何在不重新启动的情况下非破坏性地检查 grub2 是否已安装在引导扇区中或是否由 grub1 链式加载?

我们正在将几个系统从 Debian Lenny 升级到 Squeeze,我想确保我没有错过任何 grub2 安装。默认情况下,Squeeze 从 grub1 链式引导加载,您必须运行upgrade-from-grub-legacy才能升级。因此,我希望能够远程检查 grub2 是否已安装在磁盘引导扇区中,而无需重新启动,也不会覆盖引导扇区。

有什么比对硬盘早期块进行十六进制转储并尝试识别 grub2 特定的字节更简单的方法吗?

答案1

我在 grub2 debian 源代码包中偶然发现了答案。事实证明,它确实需要转储引导扇区 - 因此单独打包的脚本可能会有用。这是一个脚本(只是官方函数的包装器),它将告诉您 grub2 是否已安装到引导扇区中。它可以轻松修改以用于类似用途。

#!/bin/bash
set -e

if [ "$UID" -ne "0" ]; then
  echo Must be run as root
  exit 99
fi

scan_grub2()
{
  if ! dd if="$1" bs=512 count=1 2>/dev/null | grep -aq GRUB; then
    # No version of GRUB is installed.
    echo Grub could not be found
    return 1
  fi

  # The GRUB boot sector always starts with a JMP instruction.
  initial_jmp="$(dd if="$1" bs=2 count=1 2>/dev/null | od -Ax -tx1 | \
                 head -n1 | cut -d' ' -f2,3)"
  [ "$initial_jmp" ] || return 1
  initial_jmp_opcode="${initial_jmp%% *}"
  [ "$initial_jmp_opcode" = eb ] || return 1
  initial_jmp_operand="${initial_jmp#* }"
  case $initial_jmp_operand in
    47|4b|4c|63)
      # I believe this covers all versions of GRUB 2 up to the package
      # version where we gained a more explicit mechanism.  GRUB Legacy
      # always had 48 here.
      return 0
    ;;
  esac

  return 1
}

if scan_grub2 "/dev/sda"; then
  echo Found grub 2
else
  echo Did not find grub 2
  #Uncomment the next line to upgrade
  #upgrade-from-grub-legacy
fi

相关内容