Search code examples
bashdialogoptionmenu

how to create dynamic multiple select options using cmd dialogue in bash


I cannot seem to get the dialog box to give me multiple select options.

Here's a simplified version of what I'm trying to accomplish in a dialog box:

Menu Selection
"Pick one or more options:"
1) Option 1
2) Option 2
3) Option 3

        <select>               <exit>

Where the user sees this when selecting:

"Pick one or more options:"
 * 1) Option 1
 * 2) Option 2
 3) Option 3

            <select>               <exit>

And upon enter key on select sees: "You've selected Options 1 and 2".

Here is what I have so far:

#!/bin/bash

#initialize
MENU_OPTIONS=
COUNT=0

IFS=$'\n'

#get menu options populated from file
for i in `cat my_input_file.log`
do
       COUNT=$[COUNT+1]
       MENU_OPTIONS="${MENU_OPTIONS} $i ${COUNT} off "
done

#build dialogue box with menu options
cmd=(dialog --backtitle "Menu Selection" --checklist "Pick 1 or more options" 22 30 16)
options=(${MENU_OPTIONS})
choices=$("${cmd[@]}" "${options[@]}" 2>&1 1>/dev/tty)

#do something with the choices
for choice in $choices
do
        echo $choice selected
done

When running this (./menu.bash) on the CLI I receive the following:

Error: Expected at least 7 tokens for --checklist, have 5. selected
Use --help to list options. selected

What am I missing?


Solution

  • The issue is how you construct the options array. since you defined IFS=$'\n' in the code, using options=($MENU_OPTIONS) will create only 1 item in this array while you are looking for 9 items. To fix this issue, you can replace spaces with $'\n' in the following line of code: ( note: you will also need to unset IFS before for choice in $choices; do ...; done)

    MENU_OPTIONS="${MENU_OPTIONS} $i ${COUNT} off "
    

    to

    MENU_OPTIONS="${MENU_OPTIONS}"$'\n'${COUNT}$'\n'$i$'\n'off
    

    Or change your code to set up the options array, for example:

    #!/bin/bash
    
    #initialize
    COUNT=0
    
    while IFS=$'\n' read -r opt; do
        COUNT=$(( COUNT+1 ))
        options+=($COUNT "$opt" off)
    done <my_input_file.log
    
    #build dialogue box with menu options
    cmd=(dialog --backtitle "Menu Selection" --checklist "Pick 1 or more options" 22 30 16)
    choices=($("${cmd[@]}" "${options[@]}" 2>&1 1>/dev/tty))
    
    for choice in "${choices[@]}"; do
        echo "$choice selected"
    done