Bash 스크립트의 대화형 다중 선택

Bash 스크립트의 대화형 다중 선택


사용자가 출력 라인 중 하나를 대화식으로 선택할 수 있는 쉬운 방법이 있습니까 lsblk -f?

NAME    FSTYPE LABEL        MOUNTPOINT
sda                         
├─sda1  ntfs   WINRE_DRV    
├─sda2  vfat   SYSTEM_DRV   
├─sda3  vfat   LRS_ESP      
├─sda4                      
├─sda5  ntfs   Windows8_OS  /media/Win8
├─sda6  ntfs   Data        /media/Data
├─sda7  ext4   linux        /
├─sda8                      
├─sda9  ntfs   4gb-original 
├─sda10 ntfs   PBR_DRV      
└─sda11 ext4   home         /home

선택한 줄을 스크립트 연속에 사용하기 위해 변수에 채우나요?

사용자가 화살표 키를 사용하여 행을 위아래로 이동하고 Enter 키를 눌러 하나를 선택할 수 있다면 완벽할 것이라고 생각합니다. (이전에 설치 중 일부 구성 스크립트에서 본 것 같습니다.) 이것이 가능하지 않은 경우 최소한 사용자가 사용하도록 선택할 각 줄 앞에 숫자를 어떻게 얻을 수 있습니까 read?

답변1

당신이 찾고있는dialog. ncurses다양한 옵션을 제공하는 매우 강력한 도구입니다 . 맨페이지를 주의 깊게 읽어 보시기 바랍니다. 특히 다음 --menu옵션이 필요합니다.

   --menu text height width menu-height [ tag item ] ...
          As its name suggests, a menu box is a dialog  box  that  can  be
          used  to present a list of choices in the form of a menu for the
          user to choose.  Choices are displayed in the order given.  Each
          menu entry consists of a tag string and an item string.  The tag
          gives the entry a name to distinguish it from the other  entries
          in the menu.  The item is a short description of the option that
          the entry represents.  The user can move between  the  menu  en‐
          tries  by  pressing the cursor keys, the first letter of the tag
          as a hot-key, or the number keys 1-9. There are menu-height  en‐
          tries  displayed  in  the menu at one time, but the menu will be
          scrolled if there are more entries than that.

          On exit the tag of the chosen menu entry will be printed on dia‐
          log's  output.  If the "--help-button" option is given, the cor‐
          responding help text will be printed if  the  user  selects  the
          help button.

불행히도 공백이 포함된 명령의 출력을 사용하여 이를 합리적인 방식으로 구현하는 것은 다양한 인용 문제로 인해 상당히 복잡합니다. 어쨌든, 나는 이것을 할 수 없었고 를 사용해야 했습니다 eval. 그럼에도 불구하고 그것은 작동하고 당신이 요청한 것을 수행합니다.

#!/usr/bin/env bash
tmp=$(mktemp)
IFS=
eval dialog --menu \"Please choose a filesystem:\" 50 50 10 $(lsblk -f | sed -r 's/^/"/;s/$/" " "/' | tr $'\n' ' ') 2>$tmp
D=$(tr -d '│├└─' < $tmp | sed 's/^[ \t]*//' | cut -d' ' -f1)
printf "You chose:\n%s\n" "$D"

보다 이식 가능한 접근 방식을 위해 grep명령을 다음으로 변경하십시오.

각 출력 줄 주위에 따옴표(예: 대화 상자의 "레이블")와 따옴표로 묶인 공백(예: 대화 상자의 "항목")이 오도록 sed출력 형식을 지정 하고 개행 문자를 공백 및 트리 부분 문자로 바꿉니다.lsblktr

결과는 다음과 같습니다.

              ┌────────────────────────────────────────────────┐
              │ Please choose a filesystem:                    │  
              │ ┌────────────────────────────────────────────┐ │  
              │ │     NAME   FSTYPE LABEL MOUNTPOINT         │ │  
              │ │     sda                                    │ │  
              │ │     ├─sda1                                 │ │  
              │ │     ├─sda2                                 │ │  
              │ │     ├─sda3              /winblows          │ │  
              │ │     ├─sda4                                 │ │  
              │ │     ├─sda5                                 │ │  
              │ │     ├─sda6              /home              │ │  
              │ │     ├─sda7              /                  │ │  
              │ │     └─sda8              [SWAP]             │ │  
              │ └────↓(+)────────────────────────────90%─────┘ │  
              │                                                │  
              ├────────────────────────────────────────────────┤  
              │           <  OK  >      <Cancel>               │  
              └────────────────────────────────────────────────┘  

답변2

일반 작업에서는 커서 위의 행을 변경할 수 없습니다. 이미 새로 고쳐졌기 때문입니다. 여러분이 본 스크립트는 아마도curses 라이브러리를 사용하고 있을 것입니다. 따라서 정말로 이것을 원한다면 Python과 같은 스크립팅 언어를 사용하고 거기서 Curs 라이브러리를 사용하는 것이 좋습니다.

각 줄 앞에 숫자를 넣는 것이 훨씬 쉽습니다. 이 awk 라인을 사용하여 숫자 앞에 숫자를 넣을 수 있습니다. 아마도 더 우아한 방법이 있을 수 있지만 이것이 작동합니다. 필요에 맞게 정규식을 변경합니다.

lsblk -f | awk 'BEGIN{disk=1;} /sd[a-z][1-9]+/ {print disk, ": ",$RT;disk=disk+1;next}{print "   ", $RT}'

관련 정보