มีวิธีการดึงรายการชื่อ "menuentries" ของ GRUB หรือไม่?
ฉันต้องการผลลัพธ์ในรูปแบบที่grub-set-default
จะยอมรับ เช่น.
"Ubuntu"
"Memory test (memtest86+)"
etc.
มีวิธีการดึงรายการชื่อ "menuentries" ของ GRUB หรือไม่?
ฉันต้องการผลลัพธ์ในรูปแบบที่grub-set-default
จะยอมรับ เช่น.
"Ubuntu"
"Memory test (memtest86+)"
etc.
คำตอบ:
การใช้ awk
awk -F\' '/menuentry / {print $2}' /boot/grub/grub.cfg
grub.cfg
ช่วยให้คุณมีรายการเต็มรูปแบบของรายการเมนูทั้งหมดใน
awk -F\' '/menuentry / {print $2}' /boot/grub/grub.cfg
awk
เหล่านี้เป็นขั้นตอนแรกของฉันด้วย : \
awk -F\' '/menuentry / { print i++, $2}' /boot/grub/grub.cfg
เพื่อใช้สำหรับgrub-set-default
ล้อใช้เมาส์เลื่อนHome, End, PgUp, PgDn, ↑และ↓ปุ่มในการเลือกเมนู
สคริปต์ทุบตีใช้whiptail
แทนdialog
การแสดงเมนู ข้อดีอย่างหนึ่งคือคุณสามารถคัดลอกภาพเทอร์มินัลไปยังคลิปบอร์ดเป็น
ข้อความและวางลงในเว็บไซต์นี้เป็นข้อความ ข้อดีอื่น ๆ ได้แก่ :
dialog
ไม่ได้ติดตั้งตามค่าเริ่มต้นใน Ubuntu Server หรือ Lubuntu whiptail
ถูกรวมโดยค่าเริ่มต้นนี่คือภาพหน้าจอข้อความ:
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> │
│ │
└──────────────────────────────────────────────────────────────────────────┘
ใช้ปุ่มนำทางเพื่อไฮไลต์ตัวเลือกแล้วกดEnterเพื่อดูไดรเวอร์ของเคอร์เนลก่อนโหลดgrub
และพารามิเตอร์การบู๊ตที่ส่งผ่านgrub
ไปยังเคอร์เนลเมื่อทำการบูท:
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
สคริปต์ทุบตีgrub-menu.sh
มีเพียงหนึ่งตัวเลือกในการปรับแต่ง:
# Default for hide duplicate and triplicate options with (upstart) and (recovery mode)?
HideUpstartRecovery=false
ตั้งค่าเป็นtrue
(ซ่อนรายการพิเศษ) หรือfalse
(แสดงรายการทั้งหมด)
รูปแบบเริ่มต้นสามารถเขียนทับได้เมื่อเรียกใช้สคริปต์โดยใช้:
grub-menu.sh short
หรือ:
grub-menu.sh long
#!/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
สิ่งนี้ทำให้ฉันรำคาญใจมานานกว่าหนึ่งปี - ดังนั้นฉันจึงทำสคริปต์ที่รวดเร็วและสกปรกเพื่อทำมัน หวังว่านี่จะช่วยผู้อื่นได้ไหม
นี่เป็นชื่อที่อยู่ในคิวพุช / ป๊อป แต่ไม่ใช่การจัดทำดัชนีเมนูดังนั้นจึงอาจดีกว่านี้ แต่ฉันไปไกลเท่าที่ฉันจะใส่ใจ
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
ที่นี่คุณสามารถเห็นการคว้าหน้าจอจากกล่องของฉันแสดงว่ากำลังทำงานอยู่
ตามที่ได้รับการขอในความคิดเห็นจาก 2019/8 ฉันพูดถึงข้างต้นทำ "temp boot" ความคิดนี้เป็นสิ่งที่เริ่มต้นจากสคริปต์ของฉันและวิธีการเริ่มระบบ temp มาจากการโพสต์อีกครั้ง
# vi /etc/default/grub
# sudo update-grub
# sudo grub-set-default 0
# sudo grub-reboot 4
push
และpop
คำสั่งในคำตอบของคุณ หวังว่าฉันจะได้รู้จักพวกเขาก่อนที่ฉันจะเขียนคำตอบของฉัน
test
1. ตั้งค่า GRUB_DEFAULT เป็น GRUB_DEFAULT = บันทึก (/ etc / default / grub) 2. อัปเดตการตั้งค่า grub ใน / boot #sudo update-grub 3. ตั้งค่าระบบปฏิบัติการเริ่มต้นที่จะโหลด (ซึ่งจะโหลดทุกครั้งที่คุณรีบูตเครื่อง) # sudo grub -set-default 0 4. เมื่อต้องการโหลดระบบปฏิบัติการอื่น (หมายเลขคือหมายเลขเมนูของระบบปฏิบัติการใน /boot/grub/grub.cfg สิ่งนี้จะโหลดระบบปฏิบัติการอื่นเพียงครั้งเดียวในระหว่างการรีบูตครั้งถัดไป - รีบูตเพื่อเริ่มต้นด้วยตนเอง): sudo grub-reboot 4
นี่ควรเป็น "สตริง" ที่ถูกต้อง ...
awk -F\' '/^menuentry / {print $2}' /boot/grub/grub.cfg|cat -n|awk '{print $1-1,$1="",$0}'
ไปป์สุดท้ายลบพื้นที่สีขาวที่จุดเริ่มต้นของแต่ละแถวและแก้ไขลำดับหมายเลขให้สอดคล้องกับรายการหมายเลขด้วง ตัวอย่างผลลัพธ์:
0 Ubuntu
1 Memory test (memtest86+)
2 Memory test (memtest86+, serial console 115200)
3 Windows 10 (su /dev/sdc1)
หากคุณต้องการดูรายการทั้งหมดรวมถึงขั้นสูงคุณสามารถใช้
awk -F\' '/(^|| )nuentry / {print $2}' /boot/grub/grub.cfg|cat -n|awk '{print $1-1,$1="",$0}'
แต่ลำดับตัวเลขไม่เหมาะสำหรับใช้กับ grub-set-default
ฉันเพิ่งค้นพบว่าคุณก็สามารถใช้อัตโนมัติสมบูรณ์ (กดtab
ครั้งที่สอง) ในคำสั่งเช่นgrub-reboot
หรือgrub-set-default
และมันจะทำให้คุณมีรายชื่อของรายการเมนูการบูตที่มีอยู่ จากนั้นคุณสามารถคัดลอกชื่อที่คุณต้องการอย่างแท้จริงคุณไม่จำเป็นต้องใช้หมายเลข
น่าเสียดายด้วยเหตุผลบางอย่างการติดตั้ง Windows 7 ของฉันไม่แสดงขึ้นมา
อีกซับหนึ่งซับที่จัดการเมนูย่อย:
awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\tmenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg
นี่อาจเป็นความคิดที่ผิดพลาดได้เพราะ \ t ใช้เพื่อระบุรายการเมนูย่อย
ใน OpenSuSE grub2- หนึ่งครั้งจะมี id เมนูที่คุณสามารถใช้ในคำสั่งอื่น ๆ ไม่ได้ช่วยอะไรมากสำหรับผู้ใช้ 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)