how to customize select loop in bash - linux

I was wondering if is possible customize the select loop for bash.
I have this code:
select varName in list
do
case $varName in
pattern1)
command1;;
pattern2)
command2;;
pattern1)
command3;;
*)
echo "Error select option 1..3";;
esac
done
Output is something like this:
1) columbia 3) challenger 5) atlantis 7) pathfinder
2) endeavour 4) discovery 6) enterprise
#?
I would like to order the options in landscape view and also change the prompt [#?] by something else
Thanks

select displays the PS3 prompt.
You could try something like:
echo $PS3
old_PS3=$PS3
export PS3="make a selection :D"
list='columbia challenger atlantis pathfinder endeavour discovery enterprise'
select varName in $list
do
case $varName in
pattern1)
command1;;
pattern2)
command2;;
pattern1)
command3;;
*)
echo "Error select option 1..3";;
esac
done
# set PS3 back to original
export PS3=$old_PS3

Related

How to update variable within case statement based on user input

I have created a bash script which is essentially a wizard with a number of questions, some are multiple choice. When a multiple choice question is presented, I want the user to be able to choose a number, where each number corresponds to a different answer. I want this answer to be the variable which can be later used in the script.
I realize this is what the 'select' function is used for, but I also have a requirement when the user simply hits [ENTER] a default value is assumed. As far as I know, the 'select' function assumes an empty value of "" when the [ENTER] key is pressed (an invalid option) and re-prompts the question.
The code below is me attempting to update a variable when a number is pressed. For example when the number '1' is pressed, I want the $hash variable to updated to 'sha224'.
Is there any to achieve this using a case statement without 'select'? If not what are my alternatives?
echo
echo "Select a hashing algorithm"
echo "1 - sha224"
echo "2 - sha256"
echo "3 - sha384"
echo "4 - sha512"
while true; do
read -p "Option: [sha256]:" -e hash
case $hash in
"") hash="sha256" break 2;;
1) hash="sha224" break 2;;
2) hash="sha256" break 2;;
3) hash="sha384" break 2;;
4) hash="sha512" break 2;;
*) echo "Invalid Response: Please enter [1-4] and hit [ENTER] or hit [ENTER] to select 'sha256'";;
esac
done
Insert ; before all break.
Replace $hash with ${hash:=2} to use a default value if $hash is empty.
"") hash="sha256" break 2;; can be removed.

I'm looking to convert my MS-DOS .bat file into the equivalent linux .sh file

Basically I have to make my linux program do the same thing as my MS-DOS. Could someone help with pointers and things like that?
All the program currently does, is pull a menu for basic, advanced account creation and close.
Advanced has nothing in atm, and close does what you expect. Basic then asks you for:
Full name
Username
Password
It then saves it all in a .log file (after checking for usernames already entered) along with the exact time of creation. For example:
Badja
John Doe
123
23/04/2015 15:07:32.61
#echo off
c:
:1
set curdir=%test%
echo Welcome to OP-SYS Account creation. Please choose which mode you would like to continue in.
echo.
echo [1] Basic Account Creation
echo [2] Advanced Account Creation
echo [3] Exit
echo.
REM Menu choices
set /p cat=
if %cat%==1 (
goto 2
) else if %cat%==2 (
goto 3
) else if %cat%==3 (
goto 5
) else (
goto 4
)
:2
REM Basic account creation
echo Welcome to basic account creation.
REM user enters details
REM Username
echo Please Enter a Username
set /p username=
echo.
REM Real Name
echo Please enter your full name
set /p fullname=
echo.
REM Password
echo Please enter a password
set /p password=
echo.
REM Real name
REM Save to file
if exist %username%.log (
echo User name already exists, please enter a new user name to create an account, or return to the log in screen
goto 1
) else (
echo %username% >> %username%.log
echo %fullname% >> %username%.log
echo %password% >> %username%.log
echo %date% %time% >> %username%.log )
timeout /t 3 /nobreak > NUL
REM pause
goto end
:3
REM Advanced account creation
echo Welcome to advanced account creation.
echo This is not complete, please return to main menu.
Pause
goto 1
:4
REM Error
echo error
echo.
goto 1
:5
REM Exit
echo Goodbye.
goto end
:end
exit​
I know there are a few things that can't be copied over to linux, but I just don't know where to start, this is my basis:
PS3='Please enter your choice: '
options=("cat 1" "cat 2" "end")
select opt in "${options[#]}"
do
case $opt in
"cat 1")
echo "Basic"
;;
"cat 2")
echo "Advanced"
;;
"end")
break
;;
*) echo invalid option;;
esac
done
Any help would be amazing guys!
function choice1 {
echo "Do stuff here to create an account"
}
function choice2 {
echo "Get the point?"
}
function choice3 {
exit
}
#### Main
echo "Welcome to OP-SYS Account creation. Please choose which mode you would like to continue in."
echo
echo "[1] Basic Account Creation
[2] Advanced Account Creation
[3] Exit"
echo
read CHOICE #### This loads your choice into a variable
eval choice"$CHOICE" ### This is evaluation awesomeness
If the eval seems strange, you can go with a more traditional case...esac statement to call the various functions. I would suggest getting your menu cycling and escaping the way that you want before adding in your special function.
clear
echo "Welcome to OP-SYS Account creation. Please choose which mode you would like to continue in."
echo
echo "[1] Basic Account Creation
[2] Advanced Account Creation
[3] Exit"
echo

Basic menu BASH script in Lubuntu

I am creating a basic menu driven BASH script with 6 options, I was wondering if someone can give me a basic template of the script?
#!/bin/bash
Option 1)
Option 2)
Option 3)
Option 4)
Option 5)
Option 6) Exit
Try the select statement. Example and template:
#!/bin/bash
select choice in opt1 opt2 opt3 opt4 opt5 exit
do
case $choice in
opt1)
sl;
fortune|cowsay -d;
break;;
opt2)
cd desktop/;
mkdir textfiles;
cd textfiles;
touch 1.txt 2.txt 3.txt;
cd ..;
tar-cvf textfiles.tar textfiles/;
break;;
opt3)
echo 'You chose opt3';;
opt4)
echo 'You chose opt4';;
opt5)
echo 'You chose opt5';;
exit)
break;;
*)
echo 'Invalid option';;
esac
done
I have inserted opt1 and opt2 as examples. Remember to use break;; if you want to exit the menu loop and choose better names than optN for the options.
Edit: I just copied opt1 and opt2 from your question. I haven't looked into them. If you need help with them, you should probably ask separate questions.

Bash submenus (select opt in)

I am trying to make a complete BASH menu with submenus via select opt in.
The problem : When I go to a submenu then come back to the initial menu, it do not show options.
----------------------------------------------
Greenwatch's Kiosk debug menu
----------------------------------------------
1) Keyboard Layout, 5) Configure Kiosk's password,
2) Timezone configuration, 6) Set Proxy,
3) -, 7) Remove Proxy
4) Launch Kiosk anyway,
Enter your choice (mainmenu), press 0 to reboot: 1
1) Azerty layout (BE)
2) Querty layout (US)
3) Cancel
Enter your choice (submenu): 1
AZERTY Keyboard configured
Enter your choice (mainmenu), press 0 to reboot:
This is the code(simplified -with only one submenu- )
choose_keyboard() {
show_title "Choose your keyboard layout"
clear;
select opt in "Azerty layout (BE)" "Querty layout (US)" "Cancel"; do
case "$REPLY" in
1 ) loadkeys be-latin1; echo "AZERTY Keyboard configured"; break;;
2 ) loadkeys us; echo "QWERTY Keyboard configured"; break;;
3 ) echo "Canceled"; break;;
777 ) break;;
*) echo "This is not a valid option, retry";;
esac
done
}
main_menu() {
show_title "$title"
select opt in "${options[#]}"; do
case "$REPLY" in
0 ) show_title "See you as late as possible!"; sudo systemctl reboot;;
1 ) choose_keyboard;;
2 ) choose_timezone;;
3 ) lauch_kiosk;;
4 ) choose_password;;
5 ) choose_ipconfig;;
6 ) choose_proxy;;
7 ) choose_testlab;;
777 ) break;;
*) echo "This is not a valid option, retry";;
esac
done
}
main_menu
How could I force select to display the menu?
NOTE: If I call main_menu into the choose_keyboard function, I will certainly obtain a stackoverflow error!
When you break from the inner select, you re-enter the top (main menu) select - as you have discovered, the menu isn't displayed because you don't re-execute the commands at the beginning of the function. Instead, you can break out of the inner and outer selects at once, and have the main menu in a loop so that it gets called again, ie:
1 ) loadkeys be-latin1; echo "AZERTY Keyboard configured"; break 2;;
break 2 will break out of a select nested inside another, break 3 will break out of an additional level of nesting, etc. Then instead of just calling main_menu at the bottom, do something like:
while :; do main_menu; done
This is an infinite loop which will call main_menu whenever you break out of the main menu select command. You may not want it to be infinite, you can always test against a variable or something there.

If string contains in case statement

I'm looking to provide a case statement based on whether a substring is within a filename.
Example Input
mysql_dumps/tpmysqldump-tps_dev_russell_development-information_schema-2014-03-26.sql
Code
case $DUMPFILE in
*"tpdata"*)
database="tpdata";;
*"tpmrbs"*)
database="tpmrbs";;
*"information_schema"*)
database="information_schema";;
*"performance_schema"*)
database="performance_schema";;
*)
echo "INVALID FILE";;
esac
How do you initialize $DUMPFILE? If I run the following, the output is information_schema, which is what I expected...
#!/bin/bash
DUMPFILE=mysql_dumps/tpmysqldump-tps_dev_russell_development-information_schema-2014-03-26.sql
case $DUMPFILE in
*"tpdata"*)
database="tpdata";;
*"tpmrbs"*)
database="tpmrbs";;
*"information_schema"*)
database="information_schema";;
*"performance_schema"*)
database="performance_schema";;
*)
echo "INVALID FILE";;
esac
echo $database

Resources