我有 Debian Stretch,我想要一个自定义 grub 条目,以便在没有图形桌面的情况下运行系统。我认为这就像运行不同的运行级别一样简单,但是阅读相关内容后,我意识到systemd
一切都是不同的。
看完之后这个问题关于红帽以及这个其他对于Debian Jessie,我了解了systemd
目标,我认为我想做的是在multi-user.target中运行。
我发现了这个软呢帽链接,这个 archlinux 内核链接和另一个。他们都解释说,有一个选项“systemd.unit”可以附加到 grub 菜单项的“linux”行中。因此,我搜索了链接来解释如何创建自定义菜单条目:这个。但是,在 grub 屏幕中查看我自己的带有“e”键的自动 grub 条目,它们比链接中的条目更复杂。问题是我不知道是否必须复制自定义菜单条目中的所有内容。
setparams 'Debian gnu/linux, con linux 4.8.0-2-amd64'
load_video
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part-msdos
insmod ext2
set root='hd0,msdos5'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos5 --hint-efi=hd0,msdos5 --hint-baremetal=ahci0,msdos5 3202c741-ef05-40e4-9368-8617e7b1fb3c
else
search --no-floppy --fs-uuid --set=root 3202c741-ef05-40e4-9368-8617e7b1fb3c
fi
echo 'Cargando Linux 4.8...'
linux /vmlinuz-4.8.0-2-amd64 root=UUID=17f74892-fe09-46ec-91ca-2dca457565a1 ro quiet
echo 'Cargando imagen de memoria inicial...'
initrd /initrd.img-4.8.0-2-amd64
这是我为最后一个内核自动创建的条目。我可以简单地将所有这些复制到自定义菜单条目中并仅更改
linux /vmlinuz-4.8.0-2-amd64 root=UUID=17f74892-fe09-46ec-91ca-2dca457565a1 ro quiet
线为
linux /vmlinuz-4.8.0-2-amd64 root=UUID=17f74892-fe09-46ec-91ca-2dca457565a1 ro quiet systemd.unit=multi-user.target
?
答案1
经过几天的研究,我有 3 种方法来解决创建自定义条目以运行 Debian 的问题,Systemd
而无需从Grub
.我认为最好的方法是1。
1.新建/etc/grub.d/*配置文件
为此,我复制了/etc/grub.d/10_linux
文件作为模板:
sudo cp /etc/grub.d/10_linux /etc/grub.d/11_multiuser
原始文件创建最新内核的根条目以及“高级选项”子菜单。因此,我对11_multiuser
文件进行了一些编辑,只是为了为多用户选项创建一个新的子菜单,并在多用户模式下为每个内核创建一个新选项。在这里,我将添加一个带有修改后的行的补丁:
--- /etc/grub.d/10_linux
+++ /etc/grub.d/11_multiuser
@@ -118,6 +118,8 @@
case $type in
recovery)
title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" ;;
+ multiuser)
+ title="$(gettext_printf "%s, with Linux %s (multiuser)" "${os}" "${version}")" ;;
init-*)
title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "${type#init-}")" ;;
*)
@@ -227,57 +229,18 @@
boot_device_id=
title_correction_code=
-cat << 'EOF'
-function gfxmode {
- set gfxpayload="${1}"
-EOF
-if [ "$vt_handoff" = 1 ]; then
- cat << 'EOF'
- if [ "${1}" = "keep" ]; then
- set vt_handoff=vt.handoff=7
- else
- set vt_handoff=
- fi
-EOF
-fi
-cat << EOF
-}
-EOF
-
-# Use ELILO's generic "efifb" when it's known to be available.
-# FIXME: We need an interface to select vesafb in case efifb can't be used.
-if [ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 0 ]; then
- echo "set linux_gfx_mode=$GRUB_GFXPAYLOAD_LINUX"
-else
- cat << EOF
-if [ "\${recordfail}" != 1 ]; then
- if [ -e \${prefix}/gfxblacklist.txt ]; then
- if hwmatch \${prefix}/gfxblacklist.txt 3; then
- if [ \${match} = 0 ]; then
- set linux_gfx_mode=keep
- else
- set linux_gfx_mode=text
- fi
- else
- set linux_gfx_mode=text
- fi
- else
- set linux_gfx_mode=keep
- fi
-else
- set linux_gfx_mode=text
-fi
-EOF
-fi
-cat << EOF
-export linux_gfx_mode
-EOF
-
# Extra indentation to add to menu entries in a submenu. We're not in a submenu
# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
submenu_indentation=""
-is_top_level=true
+# para el menu de multiuser
+submenu_indentation="$grub_tab"
+if [ -z "$boot_device_id" ]; then
+ boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
+fi
+gettext_printf "Agregando entradas multiuser...\n" >&2
+echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote) (MultiUser)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
+is_top_level=false
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
case $linux in
@@ -331,34 +294,9 @@
linux_root_device_thisversion=${GRUB_DEVICE}
fi
- if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
- linux_entry "${OS}" "${version}" simple \
- "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
-
- submenu_indentation="$grub_tab"
-
- if [ -z "$boot_device_id" ]; then
- boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
- fi
- # TRANSLATORS: %s is replaced with an OS name
- echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
- is_top_level=false
- fi
-
- linux_entry "${OS}" "${version}" advanced \
- "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
-
- for supported_init in ${SUPPORTED_INITS}; do
- init_path="${supported_init#*:}"
- if [ -x "${init_path}" ] && [ "$(readlink -f /sbin/init)" != "${init_path}" ]; then
- linux_entry "${OS}" "${version}" "init-${supported_init%%:*}" \
- "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} init=${init_path}"
- fi
- done
- if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
- linux_entry "${OS}" "${version}" recovery \
- "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}"
- fi
+ linux_entry "${OS}" "${version}" multiuser \
+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} systemd.unit=multi-user.target"
+
list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
done
使用此解决方案,如果我添加/删除内核,或执行某些涉及 grub 菜单重新配置的操作,我所需的多用户条目将自动为每个内核添加。另外,我认为(但不完全确定)如果我更新 grub,我的新配置文件11_multiuser
将不会被删除,因为它不是 Grub 预定义配置文件的一部分。
2.修改/etc/grub.d/10_linux文件
这是另一种方法,但我认为这比第一种方法更糟糕。这样,您正在修改官方文件,因此您可能会破坏Grub的配置和整个系统的启动。此外,如果任何更新导致文件替换,您可能会丢失配置。这样做只有一个优点:您可以在“高级选项”子菜单中插入多用户条目。为第一种方法添加的补丁对此部分有效。无论如何,我完全不同意这种做法。
3.修改/etc/grub.d/40_custom文件
该文件旨在插入特定条目。您可以复制该条目/boot/grub/grub.cfg
并将其粘贴到此文件中,添加 systemd.. 这完全没问题,但问题是您必须为您想要的每个内核执行此操作。此外,当向系统中删除/添加新内核时,您必须手动维护此文件。另外,这些条目出现在 grub 菜单的末尾,如果您有其他操作系统(例如 Windows),那么您的自定义条目将与第一个 Linux 条目分开。
答案2
由于距您最初发表帖子已有五年了,似乎是时候提出另一个答案了。
如果您(或其他人)不需要包含旧内核的自定义菜单条目,即将推出的解决方案...
- 避免代码修改
- 采用静态菜单项,无论系统更新或重建 grub.cfg,它始终反映最新的内核
- 应出现在 grub 菜单中默认菜单项之后、其他操作系统之前
由于以前从未使用过 Debian,所以这一点并不确定,但只要 Debian 提供了最新内核和 initrd 的通用命名符号链接,如果相应地同化,这应该可以工作。如果 Debian 没有给你这样的符号链接,那么你需要一个在关闭时作为服务运行的脚本,它根据需要执行此操作并应用当前内核和 initrd 的实际名称,或者生成通用符号链接。
在 openSUSE 中,这就是在没有服务的情况下完成的方法,因为 /boot/vmlinuz 和 /boot/initrd 分别是最新内核和 initrd 的符号链接...
sudo cp --preserve /etc/grub.d/40_custom /etc/grub.d/25_custom
# locate and copy the entirety of relevant menu entries from grub.cfg, to 25_custom
sudo vim /boot/grub2/grub.cfg /etc/grub.d/25_custom
# mod menu entries in 25_custom as needed, and retain all lines unless good reason to delete any
# and do the following mods so entries no longer depend on specifically named kernel
# mod line like this...
echo 'Loading Linux 5.16.4-1-default ...'
# ...to be like this
echo 'Loading Linux ...'
# mod line like this...
linux /boot/vmlinuz-5.16.4-1-default ...
# ...to be like this. the '3' is for multi-user in openSUSE
linux /boot/vmlinuz ... 3
# mod line like this...
initrd /boot/initrd-5.16.4-1-default
# ...to be like this
initrd /boot/initrd
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
重新启动并查看。
相关信息在这里,如果有兴趣...
https://forums.opensuse.org/showthread.php/480353-12-2-New-install-Adding-options-in-grub2-menu
https://help.ubuntu.com/community/Grub2/CustomMenus