I'm trying to create script that will generate menu with filenames stored in specific folder and then allow me to print that file content with cat after entering number assigned to that file. The loop I have made works perfectly in terms of menu generation, but I don't know how to automaticly set variables and use them in order to print that files content or generate case structure (not sure which approach is better in this situation). My loop looks like this:

for file in ./menus/*; do
  echo "$number)" `basename -s .sh "$file"`
  let "number += 1"
  • 1
    thx! title error changed! Dec 11, 2016 at 15:35
  • You can use the select command
    – Ikaros
    Dec 11, 2016 at 15:39
  • I have tried, but it echoes file path. I want only file name without extention and everything in one column. I don't know how to control "select" Dec 11, 2016 at 16:04

2 Answers 2


Use dialog for that...

apt-get install dialog



BACKTITLE="Backtitle here"
TITLE="Title here"
MENU="Choose one of the following options:"

OPTIONS=(1 "Option 1"
         2 "Option 2"
         3 "Option 3")

CHOICE=$(dialog --clear \
                --backtitle "$BACKTITLE" \
                --title "$TITLE" \
                --menu "$MENU" \
                $HEIGHT $WIDTH $CHOICE_HEIGHT \
                "${OPTIONS[@]}" \
                2>&1 >/dev/tty)

case $CHOICE in
            echo "You chose Option 1"
            echo "You chose Option 2"
            echo "You chose Option 3"

Instead of complicated case / if statements, you can make a trick and use an array to store filenames inside, and then just call the file you need using it's array index:

for file in ./menus/*; do
fnames+=($(basename -s .sh $file))
#OR just fnames+=( $file )
echo "$number)" `basename -s .sh "$file"`
let "number += 1"
read -p "select a file id" fid
fid=$(($fid-1)) # reduce user input by 1 since array starts counting from zero
cat "${fnames[$fid]}.sh" # or just cat "${fnames[$fid]}" 

You can also make your jobe with a nice GUI using Yad (an advanced fork of Zenity) like bellow.
In this case you don't need numbering - you just select the file from a GUI list, and by pressing enter or click at ok you cat the selected file and you can see it's content on a new yad window.

As a single line command in bash (for testing):

fc=$(basename -s .sh $(find . -name "*.sh") |yad --list --width=500 --height=500 --center --column="File" --separator="") && cat $fc.sh |yad --text-info --width=800 --height=300

As a script:

while [ $yadb -eq "0" ];do 
    fc=$(basename -s .sh $(find . -name "*.sh") |yad --list --width=500 --height=500 --center --column="File" --separator="")
    if [ $yadb -eq "0" ]; then 
       cat $fc.sh |yad --text-info --width=800 --height=300
    # If you press cancel on yad window , then yadb will become 1 , file will not be displayed and while loop will be ended.
  • Your solution is good, but initial number reduction dosn't work. Are you sure that $fid=$(($fid-1)) is correct? Dec 11, 2016 at 15:51
  • @s-kaczmarek: Sorry, just fid=$(($fid-1)). Answer updated. Dec 11, 2016 at 15:57
  • You are welcome. If you like you can mark my answer as a solution. Dec 11, 2016 at 18:35
  • @s-kaczmarek Answer updated and enriched. Dec 13, 2016 at 13:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.