Comment lister les «entrées de menu» de GRUB en ligne de commande?

Réponses:

31

En utilisant awk

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

vous donne une liste complète de toutes les entrées de menu dans grub.cfg.

UN B
la source
1
Vous n'avez pas besoin de diriger grep vers awk, awk correspondra avec / foo /
Panther
1
awk -F\' '/menuentry / {print $2}' /boot/grub/grub.cfg
Panther
AB Je suis d'accord avec @ bodhi.zazen . Si vous modifiez et laissez-moi une note, je reviens et votez!
Fabby
@Fabby une note pour vous. OMG Ce furent mes premiers pas avec awk. : \
AB
3
Ajoutez le numéro d'entrée à la sortie: awk -F\' '/menuentry / { print i++, $2}' /boot/grub/grub.cfgà utiliser pourgrub-set-default
mikezter
8

Capture d'écran couleur (version courte)

La roue Utilisez la souris, Home, End, PgUp, PgDn, et les touches pour naviguer dans le menu.

grub-menu.sh

Capture d'écran du texte (version longue)

Le script bash utilise whiptailau lieu de dialogpour afficher le menu. Un avantage est que vous pouvez copier l'image du terminal dans le presse-papiers sous forme de texte et la coller dans ce site Web sous forme de texte. Les autres avantages incluent:

  • Prise en charge de la molette de défilement de la souris
  • Des performances plus rapides
  • dialogn'est pas installé par défaut dans Ubuntu Server ou Lubuntu. whiptailest inclus par défaut.

Voici une capture d'écran de texte:

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>                      │ 
        │                                                                          │ 
        └──────────────────────────────────────────────────────────────────────────┘ 

Mettez en surbrillance l'entrée et appuyez sur Entrée

Utilisez les touches de navigation pour mettre en surbrillance une option et appuyez sur Enterpour voir les pilotes pré-noyau chargés par grubet les paramètres de démarrage transmis grubau noyau lors du démarrage:

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 n'a qu'une seule option à modifier:

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

Définissez la valeur sur true(masquer les entrées supplémentaires) ou false(répertorier toutes les entrées).

Le format par défaut peut être remplacé lors de l'appel du script à l'aide de:

grub-menu.sh short

ou:

grub-menu.sh long

Le code:

#!/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
la source
8

Exactement, cela m'ennuie depuis plus d'un an - j'ai donc fait un script rapide et sale pour le faire. J'espère que cela aide les autres?

Cela empile les noms dans une file d'attente push / pop, mais pas l'indexation du menu, donc cela pourrait être mieux, mais je suis allé aussi loin que possible.

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

Ici, vous pouvez voir une capture d'écran de ma boîte le montrant en cours d'exécution entrez la description de l'image ici

Comme cela a été demandé dans un commentaire de 2019/8, je l'ai mentionné ci-dessus en faisant un "démarrage temporaire". Cette idée a été à l'origine de mon script, et la méthode de démarrage temporaire est venue d'un autre article et elle ressemble à ceci

  1. Définissez GRUB_DEFAULT sur GRUB_DEFAULT = enregistré # vi /etc/default/grub
  2. Mettre à jour la configuration de grub dans / boot # sudo update-grub
  3. Définir le système d'exploitation par défaut à charger (cela se chargera à chaque redémarrage de la machine) # sudo grub-set-default 0
  4. Lorsque vous devez charger un autre système d'exploitation (le numéro est un numéro de menu du système d'exploitation comme dans /boot/grub/grub.cfg, cela ne chargera l'autre système qu'une seule fois lors du prochain redémarrage - le redémarrage doit être démarré manuellement): # sudo grub-reboot 4

Réf: https://ubuntuforums.org/showthread.php?t=1310463

Lucien Murray-Pitts
la source
+1 J'aime les commandes pushet popdans votre réponse. J'aurais aimé les connaître avant d'écrire ma réponse.
WinEunuuchs2Unix
Pouvez-vous également partager grub-tempboot.sh?
Autodidact
test1. Définissez GRUB_DEFAULT sur GRUB_DEFAULT = enregistré (/ etc / default / grub) 2. Mettez à jour la configuration de grub dans / boot #sudo update-grub 3. Définissez le système d'exploitation par défaut à charger (cela se chargera à chaque redémarrage de la machine) # sudo grub -set-default 0 4. Lorsque vous devez charger un autre système d'exploitation (le numéro est un numéro de menu du système d'exploitation comme dans /boot/grub/grub.cfg, cela ne chargera l'autre système d'exploitation qu'une seule fois lors du prochain redémarrage - le redémarrage doit être démarré manuellement): sudo grub-reboot 4
Lucien Murray-Pitts
3

Cela devrait être la bonne "chaîne" ...

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

Le dernier canal supprime les espaces blancs au début de chaque ligne et corrige la séquence de numéros conformément à l'entrée du numéro de vers. Exemple de sortie:

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

Si vous aimez voir toutes les entrées, aussi les avancées, vous pouvez utiliser

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

mais la séquence de nombres ne convient pas pour une utilisation avec grub-set-default.

Stefano Bizzarri
la source
6
Cela ne montre que le menu de niveau supérieur. Le sous-menu Options avancées est manquant.
WinEunuuchs2Unix
1
Pourriez-vous expliquer ce que font les commandes canalisées et en quoi c'est mieux que la réponse acceptée ?
Melebius
Pour moi, cela a mieux fonctionné car il imprime également les numéros d'entrée
Zac
2

Je viens de découvrir que vous pouvez simplement utiliser la saisie automatique (en appuyant tabdeux fois) sur des commandes comme grub-rebootou grub-set-defaultet cela vous donnera une liste des entrées de menu de démarrage disponibles. Vous pouvez alors simplement copier le titre que vous voulez littéralement, vous n'avez pas besoin d'utiliser un numéro.

Malheureusement, pour une raison quelconque, mon installation de Windows 7 ne s'affiche pas de cette façon.

DanMan
la source
1

Un autre awk one-liner qui gère les sous-menus:

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

Cela pourrait être une pensée faillible, car \ t est utilisé pour identifier les entrées de sous-menu.

Max
la source
0

Dans OpenSuSE, grub2-once fournit l'ID de menu que vous pouvez ensuite utiliser dans d'autres commandes. Pas beaucoup d'aide pour les utilisateurs d'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)
Paranoïaque
la source
Vous devriez probablement partager l'emplacement d'où vous avez obtenu grub2-once
Charles Green
Bien qu'il s'agisse d'ubuntu, j'utilise OpenSuSE et il installe toutes les commandes grub v2 en tant que grub2 - ????. Lorsque je cherchais comment obtenir la liste du menu grub, c'est la question qui se pose indépendamment de la saveur de Linux, alors j'ai pensé que ma réponse pourrait être utile aux autres. Ce que je ne savais pas, c'est que la commande grub2-once semble être unique à suse (pas d'équivalent grub-once dans ubuntu). Je vais modifier ma réponse pour refléter cela
Paranoid
On dirait un utilitaire pratique ...
Charles Green