4

I'm searching for good explanation about making dynamic dialog --menu box in bash. I'm trying to load a list of users from a file that have structure like this:

------ user ------  
/rw412 0.2 /rx511 23.1 /sgo23 9.2  
/fs352 1.4 /...  
------ another_user ------
/rw412 0.3 / and so on...

of course the user name is between ------
i don't really know how to use loops inside dialog. I'm also trying to avoid creating additional files.

Please help

4 Answers 4

12

Here's an example of one way to use dialog. The options array can be built up in a variety of ways (see below).

#!/bin/bash
cmd=(dialog --keep-tite --menu "Select options:" 22 76 16)

options=(1 "Option 1"
         2 "Option 2"
         3 "Option 3"
         4 "Option 4")

choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)

for choice in $choices
do
    case $choice in
        1)
            echo "First Option"
            ;;
        2)
            echo "Second Option"
            ;;
        3)
            echo "Third Option"
            ;;
        4)
            echo "Fourth Option"
            ;;
    esac
done

Here's one way to build the options array:

count=0
while read -r dashes1 username dashes2
do
    if [[ $dashes1 == --*-- && $dashes2 == --*-- ]]
    then
        options+=($((++count)) "$username")
    fi
done < inputfile
Sign up to request clarification or add additional context in comments.

12 Comments

This seems likely to work but it gives me an error: temp: line 7: syntax error near unexpected token $((++c))' temp: line 7: ` options+=($((++c)) "$user")'`
@kasper: What is the shebang line in your script?
@Dennis Williamson #!bin/bash
Is there any other way to write that line?
works perfectly, I'd have searched for ages to find this elegant solution. Thx @Dennis +1 vote :-)
|
7

following the above clues and having my own ideas as well; here is another way:

#!/bin/bash

MENU_OPTIONS=
COUNT=0

for i in `ls`
do
       COUNT=$[COUNT+1]
       MENU_OPTIONS="${MENU_OPTIONS} ${COUNT} $i off "
done
cmd=(dialog --separate-output --checklist "Select options:" 22 76 16)
options=(${MENU_OPTIONS})
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
for choice in $choices
do
       " WHATEVER from HERE"
done

1 Comment

After six years this is still one of the best examples for dynamic checklist... ok the only one I found in 3 days :)
2

Ok

Following Dennis Williamson clues and my own ideas i came to something like this

#!/bin/bash
c=0
while read -r dashes1 username dashes2
do
  if [[ $dashes1 == --*-- && $dashes2 == --*-- ]]
  then
    options=("${options[@]}" "$((++c))" "$username")
  fi
done < inputfile
cmd=(dialog --backtitle "title" --menu "Select_user:" 22 38 2) #2 becouse 
i know there will be 2 options
command=`echo "${cmd[@]}" "${options[@]}" "2>file"`
$command

Now, there is an error like this: Error: Expected 2 arguments, found only 1.

Why is that??

4 Comments

Ok... i made it :D. I just took off those "" from "2>file". Awesome! Can you just tell me please how to make this command to accept two words in backtitle or menu? like --backtitle "title title"
--backtitle "title title" should work fine. Don't do the last two lines like you have them above - do them like I have them in my answer. That's what allows you to capture the selection that the user makes so you can act on it. What version of Bash are you using? That may be why the += didn't work.
bash --version shows that it's 2.05b :) and space inside "" does not work, sadly. The way i did that also gives me what i need. Selection is written to file and then to variable. with that variable i can do case or if. Or are there any dangers with my point of view?
I don't understand how you can accept your own answer when it asks why it is broken in the last sentence.
1

This is a repost of my answer from a very similar question. I arrived at this answer with the help of a cohort but couldn't find it in the wild; I think adding it here might help others.

The ${options[@]} array required the following (rather strange) structure in order to work. This was tested on bash in Ubuntu 18.04:

 #Dynamic dialogs require an array that has a staggered structure
 #array[1]=1
 #array[2]=First_Menu_Option
 #array[3]=2
 #array[4]=Second_Menu_Option

Here is bash code that reads in a directory listing from an argument and creates a dynamic menu from it:

 #! /bin/bash
 #usage: Dynamic_Menu.bash /home/user/target_directory

 declare -a array

 i=1 #Index counter for adding to array
 j=1 #Option menu value generator

 while read line
 do     
    array[ $i ]=$j
    (( j++ ))
    array[ ($i + 1) ]=$line
    (( i=($i+2) ))

 done < <(find $1 -type f) #consume file path provided as argument

 #Define parameters for menu
 TERMINAL=$(tty) #Gather current terminal session for appropriate redirection
 HEIGHT=20
 WIDTH=76
 CHOICE_HEIGHT=16
 BACKTITLE="Back_Title"
 TITLE="Dynamic Dialog"
 MENU="Choose a file:"

 #Build the menu with variables & dynamic content
 CHOICE=$(dialog --clear \
                 --backtitle "$BACKTITLE" \
                 --title "$TITLE" \
                 --menu "$MENU" \
                 $HEIGHT $WIDTH $CHOICE_HEIGHT \
                 "${array[@]}" \
                 2>&1 >$TERMINAL)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.