在 grub.cfg 中动态生成 ISO 映像的菜单项

在 grub.cfg 中动态生成 ISO 映像的菜单项

我正在制作一个多启动混合 EFI+legacy USB 记忆棒,其中 Linux 映像将存储为 .iso 文件。我想避免在 grub.cfg 中手动添加系统或每次添加图像时重新运行某些内容,因此我尝试循环遍历 USB 驱动器上的文件,为每个生成一个菜单条目(希望)加载它。以下是与我尝试对 grub.cfg 执行的操作等效的 bash:

for iso in "/boot/iso/*.iso"
do
  menuentry "$iso" --class os {
    loopback loop $iso
    linux (loop)/casper/vmlinuz
    initrd (loop)/casper/initrd.lz
  }
done

但是,GRUB shell 似乎不执行其所依赖的文件名扩展(通配符)。我也尝试过捕获类似的输出ls (hd0,gpt3)/boot/iso,但是显然既没有支持也没有计划添加它。

也许我完全失去了尝试在 for 循环中生成菜单的想法,但我希望有一些模块可以实现这一点。我还注意到,虽然确实按预期for iso in a.iso b.iso生成了多个块,但它们体内的变量没有被替换。menuentry$iso

我的问题是,如何为每个 .iso 文件创建一个菜单条目?

答案1

事实证明,GRUB shell支持通配符扩展,但前提是您首先加载 GRUB 的 regexp 模块。注意引号也很重要。

还可以menuentry通过将变量指定为参数来传递变量(将 menuentry 视为函数)。然后它们被转换为setparams调用,将它们设置为$1, $2, $3等等。以下命令成功启动 Linux Mint 映像,而无需对映像的文件名进行硬编码:

insmod regexp

for iso in /boot/iso/*.iso
do
  menuentry $iso $iso {
    echo "Booting from $2"
    loopback loop $2
    linux (loop)/casper/vmlinuz file=/cdrom/preseed/linuxmint.seed boot=casper iso-scan/filename=$2
    initrd (loop)/casper/initrd.lz
  }
done

我还发现了多重启动USB项目,它确实恰恰我试图实现的目标,使我的努力变得过时。

相关内容