kasper
kasper

Reputation: 631

Dynamic dialog --menu box in bash

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

Upvotes: 4

Views: 32345

Answers (4)

Shrout1
Shrout1

Reputation: 2607

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)

Upvotes: 1

Dennis Williamson
Dennis Williamson

Reputation: 360733

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

Upvotes: 12

a1danel
a1danel

Reputation: 71

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

Upvotes: 7

kasper
kasper

Reputation: 631

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??

Upvotes: 2

Related Questions