¿Cómo enumerar los "menuentries" de GRUB en la línea de comandos?

Respuestas:

31

Utilizando awk

awk -F\' '/menuentry / {print $2}' /boot/grub/grub.cfg 

le brinda una lista completa de todas las entradas de menú en grub.cfg.

AB
fuente
1
No necesita conectar grep a awk, awk coincidirá con el patrón con / foo /
Panther
1
awk -F\' '/menuentry / {print $2}' /boot/grub/grub.cfg
Panther
AB Estoy de acuerdo con @ bodhi.zazen . Si editas y me dejas una nota, ¡volveré y votaré!
Fabby
@Fabby una nota para ti. OMG Esos fueron mis primeros pasos con awk. : \
AB
3
Agregue el número de entrada a la salida: awk -F\' '/menuentry / { print i++, $2}' /boot/grub/grub.cfgpara usargrub-set-default
mikezter
8

Captura de pantalla en color (versión corta)

La rueda de desplazamiento del ratón uso, Home, End, PgUp, PgDn, y teclas para navegar por el menú.

grub-menu.sh

Captura de pantalla de texto (versión larga)

El script bash se usa en whiptaillugar de dialogmostrar el menú. Una ventaja es que puede copiar la imagen del terminal en el portapapeles como texto y pegarla en este sitio web como texto. Otras ventajas incluyen:

  • Soporte de rueda de desplazamiento del mouse
  • Rendimiento más rápido
  • dialogno está instalado por defecto en Ubuntu Server o Lubuntu. whiptailestá incluido por defecto.

Aquí hay una captura de pantalla de texto:

Grub Version: 2.02~beta2-36ubuntu3.15


        ┌─────────┤ Use arrow, page, home & end keys. Tab toggle option ├──────────┐
        │ Menu No. --------------- Menu Name ---------------                       │ 
        │                                                                          │ 
        │     0    Ubuntu                                                     ↑    │ 
        │     1    Advanced options for Ubuntu                                ▮    │ 
        │     1>0  Ubuntu, with Linux 4.14.31-041431-generic                  ▒    │ 
        │     1>1  Ubuntu, with Linux 4.14.31-041431-generic (upstart)        ▒    │ 
        │     1>2  Ubuntu, with Linux 4.14.31-041431-generic (recovery mode)  ▒    │ 
        │     1>3  Ubuntu, with Linux 4.14.30-041430-generic                  ▒    │ 
        │     1>4  Ubuntu, with Linux 4.14.30-041430-generic (upstart)        ▒    │ 
        │     1>5  Ubuntu, with Linux 4.14.30-041430-generic (recovery mode)  ▒    │ 
        │     1>6  Ubuntu, with Linux 4.14.27-041427-generic                  ▒    │ 
        │     1>7  Ubuntu, with Linux 4.14.27-041427-generic (upstart)        ▒    │ 
        │     1>8  Ubuntu, with Linux 4.14.27-041427-generic (recovery mode)  ▒    │ 
        │     1>9  Ubuntu, with Linux 4.14.24-041424-generic                  ▒    │ 
        │     1>10 Ubuntu, with Linux 4.14.24-041424-generic (upstart)        ▒    │ 
        │     1>11 Ubuntu, with Linux 4.14.24-041424-generic (recovery mode)  ▒    │ 
        │     1>12 Ubuntu, with Linux 4.14.23-041423-generic                  ▒    │ 
        │     1>13 Ubuntu, with Linux 4.14.23-041423-generic (upstart)        ↓    │ 
        │                                                                          │ 
        │                                                                          │ 
        │                   <Display Grub Boot>        <Exit>                      │ 
        │                                                                          │ 
        └──────────────────────────────────────────────────────────────────────────┘ 

Resalte la entrada y presione Entrar

Use las teclas de navegación para resaltar una opción y presione Enterpara ver los controladores pre-kernel cargados gruby los parámetros de arranque pasados grubal kernel al arrancarlo:

menuentry 'Ubuntu, with Linux 4.14.27-041427-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.14.27-041427-generic-advanced-f3f8e7bc-b337-4194-88b8-3a513f6be55b' {
recordfail
savedefault
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root f3f8e7bc-b337-4194-88b8-3a513f6be55b
else
search --no-floppy --fs-uuid --set=root f3f8e7bc-b337-4194-88b8-3a513f6be55b
fi
echo 'Loading Linux 4.14.27-041427-generic ...'
linux /boot/vmlinuz-4.14.27-041427-generic root=UUID=f3f8e7bc-b337-4194-88b8-3a513f6be55b ro quiet splash loglevel=0 vga=current udev.log-priority=3 fastboot kaslr acpiphp.disable=1 crashkernel=384M-2G:128M,2G-:256M $vt_handoff
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-4.14.27-041427-generic
}
Press <Enter> to continue

grub-menu.sh script bash

grub-menu.sh solo tiene una opción para ajustar:

# Default for hide duplicate and triplicate options with (upstart) and (recovery mode)?
HideUpstartRecovery=false

Establezca el valor en true(ocultar las entradas adicionales) o false(enumerar todas las entradas).

El formato predeterminado se puede anular al llamar al script usando:

grub-menu.sh short

o:

grub-menu.sh long

El código:

#!/bin/bash

# NAME: grub-menu.sh
# PATH: $HOME/bin
# DESC: Written for AU Q&A: /ubuntu//q/1019213/307523
# DATE: Apr 5, 2018. Modified: July 27, 2019
# UPDT: Scroll bar was outside of dialog box. Move windo border line.

# $TERM variable may be missing when called via desktop shortcut
CurrentTERM=$(env | grep TERM)
if [[ $CurrentTERM == "" ]] ; then
    notify-send --urgency=critical "$0 cannot be run from GUI without TERM environment variable."
    exit 1
fi

# Send output to secondary terminal such that previous history isn't cleared on exit
tput smcup

AllMenusArr=()      # All menu options.
# Default for hide duplicate and triplicate options with (upstart) and (recovery mode)?
HideUpstartRecovery=false
if [[ $1 == short ]] ; then
    HideUpstartRecovery=true    # override default with first passed parameter "short"
elif [[ $1 == long ]] ; then
    HideUpstartRecovery=false   # override default with first passed parameter "long"
fi
SkippedMenuEntry=false  # Don't change this value, automatically maintained
InSubMenu=false     # Within a line beginning with `submenu`?
InMenuEntry=false   # Within a line beginning with `menuentry` and ending in `{`?
NextMenuEntryNo=0   # Next grub internal menu entry number to assign
# Major / Minor internal grub submenu numbers, ie `1>0`, `1>1`, `1>2`, etc.
ThisSubMenuMajorNo=0
NextSubMenuMinorNo=0
CurrTag=""          # Current grub internal menu number, zero based
CurrText=""         # Current grub menu option text, ie "Ubuntu", "Windows...", etc.
SubMenuList=""      # Only supports 10 submenus! Numbered 0 to 9. Future use.

while read -r line; do
    # Example: "           }"
    BlackLine="${line//[[:blank:]]/}" # Remove all whitespace
    if [[ $BlackLine == "}" ]] ; then
        # Add menu option in buffer
        if [[ $SkippedMenuEntry == true ]] ; then
            NextSubMenuMinorNo=$(( $NextSubMenuMinorNo + 1 ))
            SkippedMenuEntry=false
            continue
        fi
        if [[ $InMenuEntry == true ]] ; then
            InMenuEntry=false
            if [[ $InSubMenu == true ]] ; then
                NextSubMenuMinorNo=$(( $NextSubMenuMinorNo + 1 ))
            else
                NextMenuEntryNo=$(( $NextMenuEntryNo + 1 ))
            fi
        elif [[ $InSubMenu == true ]] ; then
            InSubMenu=false
            NextMenuEntryNo=$(( $NextMenuEntryNo + 1 ))
        else
            continue # Future error message?
        fi
        # Set maximum CurrText size to 68 characters.
        CurrText="${CurrText:0:67}"
        AllMenusArr+=($CurrTag "$CurrText")
    fi

    # Example: "menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu" ...
    #          "submenu 'Advanced options for Ubuntu' $menuentry_id_option" ...
    if [[ $line == submenu* ]] ; then
        # line starts with `submenu`
        InSubMenu=true
        ThisSubMenuMajorNo=$NextMenuEntryNo
        NextSubMenuMinorNo=0
        SubMenuList=$SubMenuList$ThisSubMenuMajorNo
        CurrTag=$NextMenuEntryNo
        CurrText="${line#*\'}"
        CurrText="${CurrText%%\'*}"
        AllMenusArr+=($CurrTag "$CurrText") # ie "1 Advanced options for Ubuntu"

    elif [[ $line == menuentry* ]] && [[ $line == *"{"* ]] ; then
        # line starts with `menuentry` and ends with `{`
        if [[ $HideUpstartRecovery == true ]] ; then
            if [[ $line == *"(upstart)"* ]] || [[ $line == *"(recovery mode)"* ]] ; then
                SkippedMenuEntry=true
                continue
            fi
        fi
        InMenuEntry=true
        if [[ $InSubMenu == true ]] ; then
            : # In a submenu, increment minor instead of major which is "sticky" now.
            CurrTag=$ThisSubMenuMajorNo">"$NextSubMenuMinorNo
        else
            CurrTag=$NextMenuEntryNo
        fi
        CurrText="${line#*\'}"
        CurrText="${CurrText%%\'*}"

    else
        continue    # Other stuff - Ignore it.
    fi

done < /boot/grub/grub.cfg

LongVersion=$(grub-install --version)
ShortVersion=$(echo "${LongVersion:20}")
DefaultItem=0

if [[ $HideUpstartRecovery == true ]] ; then
    MenuText="Menu No.     ----------- Menu Name -----------"
else
    MenuText="Menu No. --------------- Menu Name ---------------"
fi

while true ; do

    Choice=$(whiptail --clear \
        --title "Use arrow, page, home & end keys. Tab toggle option" \
        --backtitle "Grub Version: $ShortVersion" \
        --ok-button "Display Grub Boot" \
        --cancel-button "Exit" \
        --default-item "$DefaultItem" \
        --menu "$MenuText" 24 80 16 \
        "${AllMenusArr[@]}" \
        2>&1 >/dev/tty)

    clear
    if [[ $Choice == "" ]]; then break ; fi
    DefaultItem=$Choice

    for (( i=0; i < ${#AllMenusArr[@]}; i=i+2 )) ; do
        if [[ "${AllMenusArr[i]}" == $Choice ]] ; then
            i=$i+1
            MenuEntry="menuentry '"${AllMenusArr[i]}"'"
            break
        fi
    done

    TheGameIsAfoot=false
    while read -r line ; do
        if [[ $line = *"$MenuEntry"* ]]; then TheGameIsAfoot=true ; fi
        if [[ $TheGameIsAfoot == true ]]; then
            echo $line
            if [[ $line = *"}"* ]]; then break ; fi
        fi
    done < /boot/grub/grub.cfg

    read -p "Press <Enter> to continue"

done

# Restore output to primary terminal
tput rmcup

exit 0

WinEunuuchs2Unix
fuente
8

Exactamente esto me ha estado molestando durante más de un año, así que hice un guión rápido y sucio para hacerlo. ¿Espero que esto ayude a otros?

Esto apila los nombres en una cola push / pop, pero no la indexación del menú, por lo que podría ser mejor, pero he ido tan lejos como podría ser molestado.

gawk  'BEGIN {                                                                                                                       
  l=0                                                                                                                                
  menuindex= 0                                                                                                                       
  stack[t=0] = 0                                                                                                                     
}                                                                                                                                    

function push(x) { stack[t++] = x }                                                                                                  

function pop() { if (t > 0) { return stack[--t] } else { return "" }  }                                                              

{                                                                                                                                    

if( $0 ~ /.*menu.*{.*/ )                                                                                                             
{                                                                                                                                    
  push( $0 )                                                                                                                         
  l++;                                                                                                                               

} else if( $0 ~ /.*{.*/ )                                                                                                            
{                                                                                                                                    
  push( $0 )                                                                                                                         

} else if( $0 ~ /.*}.*/ )                                                                                                            
{                                                                                                                                    
  X = pop()                                                                                                                          
  if( X ~ /.*menu.*{.*/ )                                                                                                            
  {                                                                                                                                  
     l--;                                                                                                                            
     match( X, /^[^'\'']*'\''([^'\'']*)'\''.*$/, arr )                                                                               

     if( l == 0 )                                                                                                                    
     {                                                                                                                               
       print menuindex ": " arr[1]                                                                                                   
       menuindex++                                                                                                                   
       submenu=0                                                                                                                     
     } else                                                                                                                          
     {                                                                                                                               
       print "  " (menuindex-1) ">" submenu " " arr[1]                                                                               
       submenu++                                                                                                                     
     }                                                                                                                               
  }                                                                                                                                  
}                                                                                                                                    

}' /boot/grub/grub.cfg

Aquí puedes ver una captura de pantalla de mi cuadro que muestra cómo se ejecuta ingrese la descripción de la imagen aquí

Como se solicitó en un comentario de 2019/8, mencioné anteriormente hacer un "arranque temporal". Esta idea fue lo que comenzó originalmente mi script, y el método de arranque temporal vino de otra publicación y es algo como esto

  1. Establezca GRUB_DEFAULT en GRUB_DEFAULT = guardado # vi /etc/default/grub
  2. Actualice la configuración de grub en / boot # sudo update-grub
  3. Configure el SO predeterminado para cargar (esto se cargará cada vez que reinicie la máquina) # sudo grub-set-default 0
  4. Cuando necesite cargar otro sistema operativo (el número es un número de menú del sistema operativo como en /boot/grub/grub.cfg, esto cargará otro sistema operativo solo una vez durante el próximo reinicio; el reinicio se iniciará manualmente): # sudo grub-reboot 4

Ref: https://ubuntuforums.org/showthread.php?t=1310463

Lucien Murray-Pitts
fuente
+1 Me gustan los comandos pushy popen tu respuesta. Ojalá los hubiera conocido antes de escribir mi respuesta.
WinEunuuchs2Unix
¿También puedes compartir grub-tempboot.sh?
Autodidacta el
test1. Configure GRUB_DEFAULT en GRUB_DEFAULT = guardado (/ etc / default / grub) 2. Actualice la configuración de grub en / boot #sudo update-grub 3. Configure el SO predeterminado para cargar (esto se cargará cada vez que reinicie la máquina) # sudo grub -set-default 0 4. Cuando necesite cargar otro sistema operativo (el número es un número de menú del sistema operativo como en /boot/grub/grub.cfg, esto cargará otro sistema operativo solo una vez durante el próximo reinicio; el reinicio se iniciará manualmente): sudo grub-reboot 4
Lucien Murray-Pitts
3

Esta debería ser la "cadena" correcta ...

awk -F\' '/^menuentry / {print $2}' /boot/grub/grub.cfg|cat -n|awk '{print $1-1,$1="",$0}'

La última tubería elimina el espacio en blanco al comienzo de cada fila y corrige la secuencia numérica de acuerdo con la entrada del número de grub. Salida de muestra:

0   Ubuntu
1   Memory test (memtest86+)
2   Memory test (memtest86+, serial console 115200)
3   Windows 10 (su /dev/sdc1)

Si desea ver todas las entradas, también las avanzadas, puede usar

awk -F\' '/(^|| )nuentry / {print $2}' /boot/grub/grub.cfg|cat -n|awk '{print $1-1,$1="",$0}'

pero la secuencia de números no es adecuada para usar con grub-set-default.

Stefano Bizzarri
fuente
66
Esto solo muestra el menú de nivel superior. El opciones avanzadas submenú se encuentra.
WinEunuuchs2Unix
1
¿Podría explicar qué hacen los comandos canalizados y cómo es mejor que la respuesta aceptada ?
Melebius el
Para mí, esto funcionó mejor ya que también imprime los números de entrada
Zac
2

Me acabo de enterar de que puede usar el autocompletado (presionando tabdos veces) en comandos como grub-rebooto grub-set-defaulty le dará una lista de las entradas disponibles en el menú de arranque. Luego puede copiar el título que desee literalmente, no necesita usar un número.

Desafortunadamente, por alguna razón mi instalación de Windows 7 no aparece de esa manera.

DanMan
fuente
1

Otro awk one-liner que maneja submenús:

 awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\tmenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg

Este podría ser un pensamiento falible, porque \ t se usa para identificar entradas de submenú.

Max
fuente
0

En OpenSuSE, grub2-once proporciona la identificación del menú que luego puede usar en otros comandos. Sin embargo, no hay mucha ayuda para los usuarios de Ubuntu.

# grub2-once --list
     0 openSUSE Leap 42.3
     1 Advanced options for openSUSE Leap 42.3>openSUSE Leap 42.3, with Linux 4.4.172-86-default
     2 Advanced options for openSUSE Leap 42.3>openSUSE Leap 42.3, with Linux 4.4.172-86-default (recovery mode)
     3 Advanced options for openSUSE Leap 42.3>openSUSE Leap 42.3, with Linux 4.4.165-81-default
     4 Advanced options for openSUSE Leap 42.3>openSUSE Leap 42.3, with Linux 4.4.165-81-default (recovery mode)
     5 Advanced options for openSUSE Leap 42.3>openSUSE Leap 42.3, with Linux 4.4.159-73-default
     6 Advanced options for openSUSE Leap 42.3>openSUSE Leap 42.3, with Linux 4.4.159-73-default (recovery mode)
     7 openSUSE 42.1 (x86_64) (on /dev/sda8)
     8 Advanced options for openSUSE 42.1 (x86_64) (on /dev/sda8)>openSUSE Leap 42.1 (on /dev/sda8)
     9 Advanced options for openSUSE 42.1 (x86_64) (on /dev/sda8)>openSUSE Leap 42.1, with Linux 4.1.39-56-default (on /dev/sda8)
    10 Advanced options for openSUSE 42.1 (x86_64) (on /dev/sda8)>openSUSE Leap 42.1, with Linux 4.1.39-53-default (on /dev/sda8)
    11 Advanced options for openSUSE 42.1 (x86_64) (on /dev/sda8)>Install 42.3 (on /dev/sda8)
Paranoico
fuente
Probablemente deberías compartir la ubicación de donde obtuviste grub2-once
Charles Green
Aunque se trata de ubuntu, uso OpenSuSE e instala todos los comandos de grub v2 como grub2 - ????. Cuando estaba buscando cómo obtener la lista del menú de grub, esta es la pregunta que se encuentra independientemente del sabor de Linux, así que pensé que mi respuesta podría ser útil para otros. Lo que no me di cuenta es que el comando grub2-once parece ser exclusivo de suse (no hay grub-once equivalente en ubuntu). Enmendaré mi respuesta para reflejar esto
Paranoico
Parece una práctica utilidad ...
Charles Green