Debian

為執行 systemd multiuser.target 創建 debian grub 自定義條目

  • February 7, 2022

我有 Debian Stretch,我想要一個自定義 grub 條目,以便在沒有圖形桌面的情況下執行系統。我認為這就像執行不同的執行級別一樣簡單,但讀到這一點,我意識到,systemd一切都是不同的。

在閱讀了這個關於 Red Hat 的問題以及關於 Debian Jessie 的另一個問題之後,我了解了systemd目標,我認為我想做的是在 multi-user.target 中執行。

我找到了這個 fedora 連結這個 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

?

經過幾天的研究,我有 3 種方法來解決SystemdGrub. 我認為最好的方法是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 條目分開。

引用自:https://unix.stackexchange.com/questions/342760