Após alguns dias de pesquisa, tenho 3 abordagens para o problema de criar entradas personalizadas para executar um Systemd
Debian sem área de trabalho gráfica a partir do Grub
. Eu acho que a melhor abordagem é 1.
1. Criando um novo arquivo de configuração /etc/grub.d/*
Para fazer isso, copiei o arquivo /etc/grub.d/10_linux
como modelo:
sudo cp /etc/grub.d/10_linux /etc/grub.d/11_multiuser
O arquivo original cria a entrada raiz para o kernel mais recente e também o submenu "Opções avançadas". Então, eu editei meu arquivo 11_multiuser
um pouco, apenas para criar um novo submenu para as opções multiusuário, e criar dentro de uma nova opção para cada kernel, para o modo multiusuário. Aqui vou adicionar um patch com as linhas modificadas:
--- /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
Com esta solução, se eu adicionar / remover kernels, ou executar alguma ação que envolva qualquer reconfiguração do menu grub, minhas entradas multiusuário desejadas serão automaticamente adicionadas para cada kernel. Além disso, eu acho (mas não completamente certo) que, se eu atualizar o grub, meu novo arquivo de configuração 11_multiuser
não será removido, já que não faz parte dos arquivos de configuração pré-definidos do Grub.
2. Modificando o arquivo /etc/grub.d/10_linux
Esta é outra abordagem, mas acho que isso é pior do que o primeiro. Desta forma, você está modificando o arquivo oficial, assim você pode quebrar a configuração do Grub e toda a inicialização do sistema. Além disso, se qualquer atualização levar à substituição do arquivo, você poderá perder sua configuração. Há apenas uma vantagem em fazer isso: você pode inserir suas entradas multiusuário no submenu "Opções avançadas". O patch adicionado para a primeira abordagem é parcialmente válido para isso. De qualquer forma, eu discordo totalmente desta abordagem.
3. Modificando o arquivo /etc/grub.d/40_custom
Este arquivo destina-se a inserir entradas específicas. Você poderia copiar a entrada de /boot/grub/grub.cfg
e colá-la nesse arquivo adicionando o systemd .. Está perfeitamente ok, mas o problema é que você deve fazer isso para cada kernel que você quiser. Além disso, ao remover / adicionar novos kernels ao sistema, você deve manter este arquivo manualmente. Além disso, essas entradas aparecem no final do menu do grub e, se você tiver outros sistemas operacionais, como o Windows, suas entradas personalizadas serão separadas das primeiras entradas do Linux.