Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

[Bash] Improving menu selection

Programming languages, Coding, Executables, Package Creation, and Scripting.
Post Reply
Message
Author
abbatrombone
Posts: 14
Joined: 2023-09-29 03:45
Has thanked: 4 times

[Bash] Improving menu selection

#1 Post by abbatrombone »

I am making a menu and was curious if there was a way to make it so quit was q rather than the last number. I have tried REPLY = "q" rather than

Code: Select all

REPLY = 1 + ${#sorted_options[@]} 
which did not work. I tried a case statement but was not able to get it working.

The code (please steal if you find it helpful):

Code: Select all

#!/bin/bash

##Menu for files
prompt="Please select a file to compile or run:"
options=( $(cd Java_Files && find . -maxdepth 1 -type f -name "*.java") )
##code that sorts
IFS=$'\n' sorted_options=($(sort <<<"${options[*]}"))
unset IFS ##unset, undefines a variable


PS3="$prompt "
select opt in "${sorted_options[@]}" "Quit" ; do
    if (( REPLY = 1 + ${#sorted_options[@]}  )) ; then
        exit

    elif (( REPLY > 0 && REPLY <= ${#sorted_options[@]} )) ; then
        echo  "You picked $opt which is file $REPLY"
        break

    else
        echo "Invalid option. Try another one."
    fi
done

## this grabs the file name you selected
file=$opt

##This searches for the .java file to see if it exists
##This is unneeded but is here being its working code i can use in the future

search_dir= "" ##put your dir here
file_name=$file

if [[ -d "$search_dir" ]]; then
  if [[ -f "$search_dir/$file_name" ]]; then
    echo "File $file_name exists in directory $search_dir."
	  else
    echo "File $file_name does not exist in directory $search_dir."
  fi
else
  echo "Directory $search_dir does not exist."
fi

##This searches for the .class to see if it exists

fileClass=$opt
fileClass=${fileClass//.java/}
fileClass+=".class"

if [[ -d "$search_dir" ]]; then
  if [[ -f "$search_dir/$fileClass" ]]; then
  echo "File $fileClass exists in directory $search_dir." && classExists="y"
	
  else
echo "File $fileClass does not exist in directory $search_dir." && classNotExists='y'
	
  fi
else
  echo ""
fi

##This next segment needs to be edited so if .class does not exist it compiles and then does java $file

##Compiles code if class does not exist
if [[ "$classNotExists" = "y" ]]; then
cd $search_dir && javac $file;
sleep 1 && cd $search_dir && java $file; ##has not been tested
fi

##Compiles the code if you say yes
if [[ "$classExists" = "y" ]]; then
echo "would you like to recompile the java code? y/n"
read -r Answer
fi

if [[ "$Answer" =~ [yY] ]]; then
cd  $search_dir && javac $file;
java $file
fi

##Just runs the code if you say no
if [[ "$Answer" =~ [nN] ]]; then
cd $search_dir && java $file && java $file
fi

User avatar
fabien
Forum Helper
Forum Helper
Posts: 688
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 62 times
Been thanked: 161 times

Re: [Bash] Improving menu selection

#2 Post by fabien »

The problem is a simple mistake: = assigns a value, == is a comparison operator.

Code: Select all

$> declare -i num=5
$> (( num == 6 )) || echo $num
5
$> (( num = 6 )) && echo $num
6

Code: Select all

#!/bin/bash

prompt="Please select a file to compile or run:"
options=( "javaFile2.java" "java  File1.java" "javaFile0.java" )
### change IFS in the subshell only
readarray -t sorted_options < <(IFS=$'\n'; sort <<<"${options[*]}")

PS3="$prompt "
select opt in "${sorted_options[@]}" "Quit" ; do
   if [[ "$REPLY" =~ ^[qQ](uit)*$ ]] || (( REPLY == 1 + ${#sorted_options[@]} )); then
      exit
   elif (( REPLY > 0 && REPLY <= ${#sorted_options[@]} )) ; then
      echo  "You picked $opt which is file $REPLY"
      break
   else
      echo "Invalid option. Try another one."
   fi
done
Note that this works because non-digits are evaluated to 0

Code: Select all

$> declare -i num
$> myvar=w; (( myvar == 0 )) && echo myvar
w
$> num=w; (( num == 0 )) && echo $num
0

abbatrombone
Posts: 14
Joined: 2023-09-29 03:45
Has thanked: 4 times

Re: [Bash] Improving menu selection

#3 Post by abbatrombone »

That worked wonderfully. Is there any way so that it displays as q) Quit at all or does

Code: Select all

select opt in
lock me into a numerical value?

User avatar
fabien
Forum Helper
Forum Helper
Posts: 688
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 62 times
Been thanked: 161 times

Re: [Bash] Improving menu selection

#4 Post by fabien »

abbatrombone wrote: 2024-03-03 21:21 Is there any way so that it displays as q) Quit at all or does

Code: Select all

select opt in
lock me into a numerical value?
The manual is quite clear, I'm afraid :)
man 1 bash wrote:select name [ in word ] ; do list ; done
The list of words following in is expanded, generating a list of items, and the set of expanded words is printed on the standard error, each preceded by a number.
select is handy, but if you want something more advanced you'll have to code it.

Post Reply