Bagaimana cara mendaftar "menuentries" GRUB di command-line?

Jawaban:

31

Menggunakan awk

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

memberi Anda daftar lengkap semua entri menu di grub.cfg.

AB
sumber
1
Anda tidak perlu menggunakan pipa grep hingga awk, awk akan berpola cocok dengan / foo /
Panther
1
awk -F\' '/menuentry / {print $2}' /boot/grub/grub.cfg
Panther
AB Saya setuju dengan @ bodhi.zazen . Jika Anda mengedit dan meninggalkan saya catatan, saya akan kembali dan mendukung!
Fabby
@Buat catatan untuk Anda. OMG Itu adalah langkah pertama saya awk. : \
AB
3
Tambahkan nomor entri ke output: awk -F\' '/menuentry / { print i++, $2}' /boot/grub/grub.cfguntuk digunakan untukgrub-set-default
mikezter
8

Tangkapan layar berwarna (versi singkat)

Roda menggunakan mouse scroll, Home, End, PgUp, PgDn, dan tombol untuk menavigasi menu.

grub-menu.sh

Tangkapan layar Teks (versi panjang)

Skrip bash menggunakan whiptailalih-alih dialoguntuk menampilkan menu. Salah satu keuntungannya adalah Anda dapat menyalin gambar terminal ke clipboard sebagai teks dan menempelkannya ke situs web ini sebagai teks. Keuntungan lain termasuk:

  • Dukungan roda gulir mouse
  • Performa lebih cepat
  • dialogtidak diinstal secara default di Ubuntu Server atau Lubuntu. whiptaildisertakan secara default.

Berikut cuplikan layar teks:

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

Sorot entri dan tekan Enter

Gunakan tombol navigasi untuk menyorot opsi dan tekan Enteruntuk melihat driver pra-kernel dimuat oleh grubdan parameter boot yang dilewatkan grubke kernel saat mem -bootnya :

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 skrip bash

grub-menu.sh hanya memiliki satu opsi untuk mengubah:

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

Tetapkan nilai ke true(sembunyikan entri tambahan) atau false(daftarkan semua entri).

Format default dapat diganti ketika memanggil skrip menggunakan:

grub-menu.sh short

atau:

grub-menu.sh long

Kode:

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

Tepatnya ini telah mengganggu saya selama lebih dari setahun - jadi saya melakukan script cepat dan kotor untuk melakukannya. Semoga ini bisa membantu orang lain?

Ini menumpuk nama-nama dalam antrian push / pop, tetapi tidak menu pengindeksan jadi itu bisa lebih baik tapi saya sudah sejauh yang saya bisa terganggu.

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

Di sini Anda dapat melihat ambil layar dari kotak saya yang menunjukkan itu berjalan masukkan deskripsi gambar di sini

Seperti yang telah diminta dalam komentar dari 2019/8 yang saya sebutkan di atas melakukan "temp boot". Ide ini adalah apa yang awalnya dimulai skrip saya, dan metode boot temp berasal dari posting lain dan berjalan seperti ini

  1. Setel GRUB_DEFAULT menjadi GRUB_DEFAULT = disimpan # vi /etc/default/grub
  2. Perbarui konfigurasi grub di / boot # sudo update-grub
  3. Tetapkan OS default untuk memuat (ini akan memuat setiap kali Anda menyalakan ulang mesin) # sudo grub-set-default 0
  4. Ketika perlu memuat OS lain (nomor adalah nomor menu OS seperti di /boot/grub/grub.cfg, ini akan memuat OS lain hanya sekali selama reboot berikutnya - reboot akan dimulai secara manual): # sudo grub-reboot 4

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

Lucien Murray-Pitts
sumber
+1 Saya suka pushdan popperintah dalam jawaban Anda. Seandainya saya tahu mereka sebelum saya menulis jawaban saya.
WinEunuuchs2Unix
Bisakah Anda juga membagikan grub-tempboot.sh?
Autodidact
test1. Set GRUB_DEFAULT ke GRUB_DEFAULT = disimpan (/ etc / default / grub) 2. Perbarui konfigurasi grub di / boot #sudo update-grub 3. Tetapkan OS default untuk dimuat (ini akan memuat setiap kali Anda menyalakan ulang mesin) # sudo grub -set-default 0 4. Ketika perlu memuat OS lain (nomor adalah nomor menu OS seperti di /boot/grub/grub.cfg, ini akan memuat OS lain hanya sekali selama reboot berikutnya - reboot akan dimulai secara manual): sudo grub-reboot 4
Lucien Murray-Pitts
3

Ini harus menjadi "string" yang tepat ...

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

Pipa terakhir menghapus spasi putih di awal setiap baris dan memperbaiki urutan nomor sesuai dengan entri nomor grub. Output sampel:

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

Jika Anda ingin melihat semua entri, juga entri tingkat lanjut, Anda dapat menggunakannya

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

tetapi urutan angka tidak cocok untuk digunakan dengan grub-set-default.

Stefano Bizzarri
sumber
6
Ini hanya menampilkan menu tingkat atas. The Advanced Options sub-menu yang hilang.
WinEunuuchs2Unix
1
Bisakah Anda menjelaskan apa yang dilakukan perintah pipa dan bagaimana itu lebih baik daripada jawaban yang diterima ?
Melebius
Bagi saya, ini bekerja lebih baik karena mencetak juga nomor entri
Zac
2

Saya baru tahu bahwa Anda bisa menggunakan pelengkapan otomatis (menekan tabdua kali) pada perintah seperti grub-rebootatau grub-set-defaultdan itu akan memberi Anda daftar entri menu boot yang tersedia. Anda kemudian dapat menyalin judul yang Anda inginkan secara harfiah, Anda tidak perlu menggunakan nomor.

Sayangnya, karena alasan tertentu instalasi Windows 7 saya tidak muncul seperti itu.

DanMan
sumber
1

Satu liner awk lainnya yang menangani submenu:

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

Ini mungkin pemikiran yang keliru, karena \ t digunakan untuk mengidentifikasi entri submenu.

Maks
sumber
0

Di OpenSuSE, grub2-once menyediakan id menu yang dapat Anda gunakan di perintah lain. Tidak banyak membantu bagi pengguna 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)
Paranoid
sumber
Anda mungkin harus membagikan lokasi yang Anda dapatkan dari grub2-sekali
Charles Green
Meskipun ini tentang ubuntu saya menggunakan OpenSuSE dan menginstal semua perintah grub v2 sebagai grub2 - ????. Ketika saya sedang mencari cara untuk mendapatkan daftar menu grub, ini adalah pertanyaan yang ditemukan terlepas dari rasa linux jadi saya pikir tanggapan saya mungkin membantu orang lain. Apa yang saya tidak sadari adalah bahwa perintah grub2-once tampaknya unik untuk digunakan (tidak ada setara grub-sekali di ubuntu). Saya akan mengubah jawaban saya untuk mencerminkan ini
Paranoid
Tampak seperti utilitas praktis ...
Charles Green