GRUB의 "메뉴 항목"을 명령 줄에 나열하는 방법?


답변:


31

사용 awk

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

의 모든 메뉴 항목 전체 목록을 제공합니다 grub.cfg.


1
grep을 awk로 파이프 할 필요는 없습니다. awk는 / foo /와 패턴 일치를합니다
Panther

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

AB 나는 @ bodhi.zazen에 동의합니다 . 당신이 편집하고 메모를 남겨두면, 나는 돌아와 투표를한다!
Fabby

@Fabby 당신을위한 메모. 이것들과의 첫 걸음 awk이었습니다. : \
AB

3
출력에 항목 번호를 추가하십시오.awk -F\' '/menuentry / { print i++, $2}' /boot/grub/grub.cfggrub-set-default
mikezter

8

컬러 스크린 샷 (짧은 버전)

사용은 마우스 스크롤 휠, Home, End, PgUp, PgDn, 키를 사용하여 메뉴를 탐색 할 수 있습니다.

grub-menu.sh

텍스트 스크린 샷 (긴 버전)

bash 스크립트는 whiptail대신 dialog메뉴를 표시하는 데 사용합니다. 한 가지 장점은 터미널 이미지를 클립 보드에 텍스트 로 복사하여이 웹 사이트에 텍스트로 붙여 넣을 수 있다는 것입니다. 다른 장점은 다음과 같습니다.

  • 마우스 스크롤 휠 지원
  • 빠른 성능
  • dialogUbuntu 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를 누르십시오.

탐색 키를 사용하여 옵션을 강조 표시하고을 눌러 부팅 할 때로 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 bash 스크립트

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


8

정확히 이것은 1 년 이상 나를 귀찮게했습니다. 그래서 나는 빠르고 더러운 스크립트를 수행했습니다. 이것이 다른 사람들을 돕기를 바랍니다.

이것은 푸시 / 팝 큐에 이름을 쌓아 올리지 만 메뉴 인덱싱은 아니므로 더 좋을 수는 있지만 귀찮게 할 수 있습니다.

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"를 언급했습니다. 이 아이디어는 원래 내 스크립트에서 시작된 것이었고 임시 부팅 방법은 다른 게시물에서 왔으며 다음과 같이 진행됩니다.

  1. GRUB_DEFAULT를 GRUB_DEFAULT = saved로 설정하십시오. # vi /etc/default/grub
  2. / boot에서 grub 설정 업데이트 # sudo update-grub
  3. 기본 OS를로드하도록 설정 (시스템을 재부팅 할 때마다로드 됨) # sudo grub-set-default 0
  4. 다른 OS를로드해야하는 경우 (번호는 /boot/grub/grub.cfg에서와 같이 메뉴 번호 OS 임) 다음에 다시 부팅하는 동안 다른 OS를 한 번만로드합니다. 재부팅하면 수동으로 시작됩니다. # sudo grub-reboot 4

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


+1 나는 당신의 대답에서 pushpop명령을 좋아합니다 . 내 대답을 쓰기 전에 알고 있었으면 좋겠다.
WinEunuuchs2Unix

grub-tempboot.sh을 공유 할 수 있습니까?
Autodidact

test1. GRUB_DEFAULT를 GRUB_DEFAULT = saved (/ etc / default / grub)로 설정합니다. 2. / boot #sudo update-grub에서 grub 구성을 업데이트합니다. 3. 기본 OS를로드하도록 설정합니다 (시스템을 재부팅 할 때마다로드 됨) -set-default 0 4. 다른 OS를로드해야 할 경우 (번호는 /boot/grub/grub.cfg와 같이 OS의 메뉴 번호 임) 다음에 다시 부팅하는 동안 다른 OS를 한 번만로드합니다. 재부팅하면 수동으로 시작됩니다. sudo grub-reboot 4
Lucien Murray-Pitts

3

이것은 올바른 "문자열"이어야합니다 ...

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와 함께 사용하기에 적합하지 않습니다.


6
최상위 메뉴 만 표시됩니다. 고급 옵션 하위 메뉴가 없습니다.
WinEunuuchs2Unix

1
파이프 된 명령의 기능과 허용 된 응답 보다 더 나은 방법을 설명 할 수 있습니까?
Melebius

저에게 이것은 엔트리 번호도 인쇄 할 때 더 잘 작동했습니다
Zac

2

방금 또는 tab같은 명령에서 자동 완성 ( 두 번 누름 )을 사용할 수 있으며 사용 가능한 부팅 메뉴 항목 목록이 표시됩니다. 그런 다음 문자 그대로 원하는 제목을 복사하면 숫자를 사용할 필요가 없습니다.grub-rebootgrub-set-default

불행히도 어떤 이유로 Windows 7 설치가 그런 식으로 표시되지 않습니다.


1

하위 메뉴를 처리하는 다른 awk one-liner :

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

하위 메뉴 항목을 식별하기 위해 \ t가 사용되기 때문에 이것은 잘못된 생각 일 수 있습니다.


0

OpenSuSE에서 grub2-once는 다른 명령에서 사용할 수있는 메뉴 ID를 제공합니다. 우분투 사용자에게는별로 도움이되지 않습니다.

# 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)

당신은 아마 grub2-once에서 얻은 위치를 공유해야합니다
Charles Green

이것은 우분투에 관한 것이지만 OpenSuSE를 사용하고 모든 grub v2 명령을 grub2-????로 설치합니다. grub 메뉴 목록을 얻는 방법을 검색 할 때 Linux 풍미에 관계없이 발견되는 질문이므로 내 응답이 다른 사람들에게 도움이 될 것이라고 생각했습니다. 내가 알지 못하는 것은 grub2-once 명령이 독특하게 나타납니다 (우분투에서는 그루브가 없음). 이것을 반영하기 위해 내 대답을 수정하겠습니다
Paranoid

편리한 유틸리티 인 것 같습니다 ...
Charles Green
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.