Code optimization

Hi all

I wrote below code:

#!/bin/sh

R='\033[0;31m'
N='\033[0m'

echo " ";
echo -e "${R}Choose database $N"
echo " ";
echo "1 - db_a"
echo "2 - db_b"
echo "3 - db_c"
echo "4 - db_g"
echo "5 - db_o"
echo "6 - db_e"
echo "7 - db_k"
echo "8 - db_t"
echo " "


read NUM

case $NUM in
       1)
                export ORACLE_SID=db_a
                export HOST=db_a_qa
                 ;;
       2)
		export ORACLE_SID=db_b
                export HOST=db_b_qa
                ;;
       3)
		export ORACLE_SID=db_c
                export HOST=db_c_qa
                ;;
       4)
		export ORACLE_SID=db_g
                export HOST=db_g_qa
                ;;
       5)
		export ORACLE_SID=db_o
                export HOST=db_o_qa
                 ;;
       6)
		export ORACLE_SID=db_e
                export HOST=db_e_qa
                ;;
       7)
		export ORACLE_SID=db_k
                export HOST=db_k_qa
                ;;
       8)
		export ORACLE_SID=db_t
                export HOST=db_t_qa
                ;;

       *) echo -e  "${R}Invalid number!${N}" 
				;;
esac
echo " "

do you have any idea how to optimize my code ? (to make it shorter eg.)

Like so?

#!/bin/sh

R='\033[0;31m'
N='\033[0m'

OPTIONS="1 - db_a
2 - db_b
3 - db_c
4 - db_g
5 - db_o
6 - db_e
7 - db_k
8 - db_t"
set -- $OPTIONS

printf "${R}Choose database ${N}\n\n%s\n\n" "$OPTIONS"

read NUM
case $NUM in 
   [1-8]) 
                eval export ORACLE_SID=\$\{$((3*NUM))\}
                export HOST=${ORACLE_SID}_qa
                ;;

       *)       printf "${R}Invalid number!${N}\n"
                ;;
esac
echo

Or can it be bash as well?

Sorry my mistake, script should be only bash.

#!/bin/bash

With bash you have the select statement. Try

OPTIONS="db_a db_b db_c db_g db_o db_e db_k db_t"
PS3="Choose database: "
select ORACLE_SID in $OPTIONS; do echo $ORACLE_SID; HOST=${ORACLE_SID}_qa; echo $HOST; done
2) db_b
3) db_c
4) db_g
5) db_o
6) db_e
7) db_k
8) db_t
Choose database: 4
db_g
db_g_qa
Choose database: 8
db_t
db_t_qa
Choose database: 

Press <Ctrl-D> to quit...

1 Like

To add your color options and answer checking and menu finishing, try something like this:

#!/bin/bash
R=$'\e[0;31m'
N=$'\e[0m'

OPTIONS=( db_a db_b db_c db_g db_o db_e db_k db_t )
PS3=$'\n'"${R}Choose database ${N}"

select ORACLE_SID in "${OPTIONS[@]}"; do
  if [[ $REPLY == [1-8] ]]; then
    export ORACLE_SID
    export HOST=${ORACLE_SID}_qa
    break
  fi
  printf "${R}Invalid number!${N}\n"
done 
echo
1 Like

With my system, above PS3 assignment doesn't give satisfying results. man bash :

Note - it is NOT expanded!

You may want to try this circumnavigation:

PS3=$(printf $'\n'"${R}Choose database ${N}")

Note that I did not use expansions. Those should be literal characters..

Compare:

$ R=$'\e[0;31m'; N=$'\e[0m'; var=$'\n'"${R}Choose database ${N}" dash -c 'echo "$var"'

Choose database 
1 Like

Yes. After trying and finding out myself, I noticed the subtle difference in R and N assignments between post#2 and #5 - the $ sign!

Simply break the loop if ORACLE_SID got a value!
(You do not need to check the boundaries. Imagine you have 10+ items...)

#!/bin/bash
R=$'\e[0;31m'
N=$'\e[0m'

OPTIONS=(
 db_a db_b db_c db_g
 db_o db_e db_k db_t
)
PS3=$'\n'"${R}Choose database ${N}"

select ORACLE_SID in "${OPTIONS[@]}"
do
  [[ -n $ORACLE_SID ]] && break
  printf "${R}Invalid number!${N}\n"
done

#^D pressed?
[[ -n $ORACLE_SID ]] || exit

export ORACLE_SID HOST=${ORACLE_SID}_qa
echo "HOST=$HOST"
2 Likes

You might as well consider this adaption of your original code:

R=$'\033[0;31m'
N=$'\033[0m'
cat <<-EOF

        1 - db_a
        2 - db_b
        3 - db_c
        4 - db_g
        5 - db_o
        6 - db_e
        7 - db_k
        8 - db_t

${R}Choose database $N

        EOF

read NUM
export ORACLE_SID=db_$(printf "\\$(printf "%o" $((0140+NUM)))")
export HOST=${ORACLE_SID}_qa
echo $ORACLE_SID, $HOST

Thank you all, finally I use MadeInGermany code modification.

Hi primo102...

Just an observation and slightly off topic and assumes bash.
I have no idea which OS you are using but there are now various Linux flavours that use terminal __windows__ of varying sizes.
I am assuming that you are using the standard size of 80x24, however.....
I have seen 60x21 - (the smallest I have seen), 70x23, 77x25, 80x25 and a couple of others.
Some of the default terminal windows inside certain Linux flavours will not be able to be resized on the fly, the 60x21 one was just an example, so you might have to work around those limits!
You can check yours by using stty size and this will give the figures in reverse, something like 24 80 ...
For those terminal windows that CAN be resized on the fly you can use this at the start of your script after the "shebang":

printf "%b" "\x1B[8;24;80t"

If you really want to make it pretty some of these terminal windows can even be written into the title bar:

printf "%b" "\x1B]0;Your title bar text here.\x07"

And return back to default title:

printf "%b" "\x1B]0;\x07"

Again, purely just an observation as you are using a neatly ordered selection process.