#!/bin/bash
function advancedMenu() {
ADVSEL=$(whiptail --title "Advanced Menu" --fb --menu "Choose an option" 15 60 4 \
"1" "Delete group" \
"2" "Create login name" \
"3" "Exit" 3>&1 1>&2 2>&3)
case "$ADVSEL" in
1)
echo "Option 1"
whiptail --title "Option 1" --msgbox "You chose group deleting. Exit status $?" 8 45
bash ./script3;;
2)
echo "Option 2"
whiptail --title "Option 1" --msgbox "You chose login name creating. Exit status $?" 8 45
bash ./script;;
3)
echo "Option 3"
whiptail --title "Option 1" --msgbox "You chose exit. Exit status $?" 8 45
;;
esac
}
advancedMenu
I don't know how to loop my case statement. I have user friendly interface here. Someone chooses 1\2 or exit. 1 and 2 runs another scripts. So when 1 is clicked and scripted is finished, I need the main menu back until case 3 is clicked. I will be grateful for your help!
#!/bin/bash
export NEWT_COLORS='
window=white,blue
border=white,green
textbox=white,green
button=black,white
'
{
for ((i = 0 ; i <= 100 ; i += 1)); do
sleep 1
echo $i
done
} | whiptail --gauge "Wait..." 6 60 0
touch 35_2.csv
while read line; do
IFS=","
set -- $line
group_name=$1
student_name=$2
student_name=`echo $student_name | tr -d '\r\n' `
login_name=`echo $student_name | sed 's/[b\`]//g;'`
login_name=`echo $login_name | sed 'y/абвгдеєзиіїйклмнопрстуфхь/abvgdeeziiijklmnoprstufh_/'`
login_name=`echo $login_name | sed 's/ /_/g; s/С†/ts/g; s/Р¶/zh/g; s/С‡/ch/g; s/С€/sh/g; s/С‰/sh/g; s/СЋ/yu/g; s/СЏ/ya/;'`
echo "$group_name, $student_name, $login_name" >> 35_2.csv
done < 35_2.csv
Don't look at wrong encoding. Your decision seemed to be right. The first script runs then menu goes back. However, when I start the second script the menu does not go back. Attached the 2nd's script code.
Simply put a while loop around it.
#!/bin/bash
function advancedMenu() {
while :; do
ADVSEL=$(whiptail --title "Advanced Menu" --fb --menu "Choose an option" 15 60 4 \
"1" "Delete group" \
"2" "Create login name" \
"3" "Exit" 3>&1 1>&2 2>&3)
case "$ADVSEL" in
1)
echo "Option 1"
whiptail --title "Option 1" --msgbox "You chose group deleting. Exit status $?" 8 45
bash ./script3;;
2)
echo "Option 2"
whiptail --title "Option 1" --msgbox "You chose login name creating. Exit status $?" 8 45
bash ./script;;
3)
echo "Option 3"
whiptail --title "Option 1" --msgbox "You chose exit. Exit status $?" 8 45
return
;;
esac
done
}
advancedMenu
I'm not sure what you expect Exit status $? to show. $? is the exit status of the echo statement on the previous line, so it will almost always just be 0.
Related
I just started to learn bash and create a GUI with Dialog, but I'm having a problem with my program, any help will be appreciate it. Thanks
I want to create a program which will display a dialog which will ls only directories from the current folder:
display_folders()
{
while true; do
let count=0 #define counting variable
w=() #define working array
while read -r line; do #process file by file
let count=$count+1
w+=("$line" "$line")
done < <(ls -d */)
file=$(dialog --title "List directory" --cancel-label "Exit" --no-tags --menu "Please choose one folder: " 10 40 0 "${w[#]}" 3>&2>
#clear
exit_status=$?
echo $exit_status
case $exit_status in
1) echo "Program terminated"
exit ;;
255) echo "Program aborted"
exit 1 ;;
esac
echo "this is $file"
case "$file" in
*)
cd $file
display_result "$file" ;;
esac
done
}
After selecting the specified dir (for example ANIMALS) I want to cd into it and make some actions (the code is just for the 1 selection)
display_result()
{
while true; do
selection=$(dialog --title "folder" \
--cancel-label "Exit" \
--menu "Choose an action: " 10 40 0 \
"1" "List details about files" \
"2" "Search for word" \
"3" "Generate CSV" \
"4" "More info CSV" \
"5" "Search file" \
3>&2 2>&1 1>&3)
exit_status=$?
case $exit_status in
1) break ;;
255) echo "Program aborted"
exit 1 ;;
esac
case $selection in
1 )
result=$(ls -lt)
display_file_details ;;
esac
done
}
display_file_details()
{
dialog --title "file details" --no-collapse --msgbox "$result" 0 0
}
The problem is, in the selected folder (ANIMALS) I have another folder too (for example OTHERS), when I am ls all from the folder ANIMALS it will display me everything (which is good), but after I exit from the display --msgbox will display me another --menu only with OTHERS folder, and the display_result for it, if I exit from this too, the program will exit with 1 code.
What I want is to cd into ANIMALS, which is the dir from current folder, then list the options (1,2,3,4,5), and after exit from the options display I want to take me back to my current folder with ANIMALS in it.
You don't need this 'while true; do' loops. Create first dialog:
dialog1(){
list=( */ )
folder=$( dialog --title "List directory" --cancel-label "Exit" \
--no-items --menu "Please choose one folder: " \
--output-fd 1 10 40 0 ${list[#]///} )
echo $folder
dialog2
}
And the second like this:
dialog2(){
# another dialog here
# some code here
dialog1 # run first dialog again
}
And start first dialog:
dialog1
p.s. check out my projects sshto and kube-dialog created via dialog.
Thank's #Ivan but this is not what I wanted.
I solved it by going back with a dir in the same case :
display_file_details()
{
dialog --title "file details" --no-collapse --msgbox "$1" 0 0
}
dialog1(){
list=( */ )
folder=$( dialog --title "List directory" --cancel-label "Exit" \
--no-items --menu "Please choose one folder: " \
--output-fd 1 10 40 0 ${list[#]///} )
exit_status=$?
echo "$exit_status dialog1"
case $exit_status in
1 | 255)
return 0
;;
*)
diag2_return=255
while [ "$diag2_return" -ne "0" ]; do
dialog2 $folder
diag2_return=$?
done
esac
return 1
}
dialog2(){
echo "hereeeeeeeeee $1"
selection=$(dialog --title "folder" --cancel-label "Exit" \
--menu "Choose an action: " --output-fd 1 10 40 0 \
"1" "List details about files" \
"2" "Search for word" \
"3" "Generate CSV" \
"4" "More info CSV" \
"5" "Search file" )
exit_status=$?
echo "$exit_status dialog2"
case $exit_status in
1 | 255)
return 0
;;
esac
case $selection in
1 )
cd "$1"
result=$(ls -lt)
display_file_details "$result"
cd ..
;;
esac
return 1
}
diag_return=255
while [ "$diag_return" -ne "0" ]; do
dialog1
diag_return=$?
done
On this code:
#!/bin/bash
for i in {1..50}; do
#if [ ! $(jobs -rp | grep $pid) ]; then
dialog --msgbox "Instance initilation failure!" 0 0
# return 1
#fi
sleep 1
echo $((i * 2))
done | dialog --title "Initiating instance" --gauge "Please wait..." 10 60 0
The dialog --msgbox is being piped into the gauge and for this reason the gauge doesn't work and the msgbox doesn't appear.
Is it possible to avoid this to happen? To display the msgbox and then enter the return?
Maybe just put the dialog call inside the loop.
I would suggest the following:
#!/bin/bash
for i in {1..5}; do
#if [ ! $(jobs -rp | grep $pid) ]; then
dialog --msgbox '"Instance initilation failure!"' 0 0
# return 1
#fi
(
echo "$((i * 2))"
sleep 1
) | dialog --title "Initiating instance" --gauge "Please wait..." 10 60 0
done
The link below:
https://serverfault.com/questions/144939
It correctly shows how to create a menu using the "dialog" command but does not show how to create the "select all" shortcut button.
How to create the "Select all" button?
Like this:
#!/bin/bash
onoff=off # all unset by defaul
dialog1(){ dialog --output-fd 1 --extra-button --extra-label "Select All" --checklist "Select options:" 0 0 0 "$#"; }
dialog2(){ choices=$(dialog1 "${options[#]}"); }
set_options(){ # make options array dynamic
options=(
1 "Option 1" $onoff
2 "Option 2" $onoff
3 "Option 3" $onoff
4 "Option 4" $onoff
)
}
set_option
dialog2
case $? in # if 'Select All' presssed
3) onoff=on # set all to on
set_options # reassemble options
dialog2;; # and run dialog again
esac
clear
echo $choices
Ivan, thank you.
Taking a cue from your solution, merging it with that of the link:
https://serverfault.com/questions/144939
and improving the code in my own way, I got this solution:
#!/bin/bash
onoff=off
cmd=(dialog --output-fd 1 --separate-output --extra-button --extra-label "Select All" --cancel-label "Select None" --checklist "Select options:" 0 0 0)
load-dialog () {
options=(
1 "Option 1" $onoff
2 "Option 2" $onoff
3 "Option 3" $onoff
4 "Option 4" $onoff
)
choices=$("${cmd[#]}" "${options[#]}")
}
load-dialog
exit_code="$?"
while [[ $exit_code -ne 0 ]]; do
case $exit_code in
1) clear; onoff=off; load-dialog;;
3) clear; onoff=on; load-dialog;;
esac
exit_code="$?"
done
clear
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
sleep infinity
I have an options menu function:
function()
{
echo "1 Option 1"
echo "2 Option 2"
echo "3 Option 3"
echo "q Exit"
read -p "Select 1-3 ή \"q\" to quit: " i
case "$i" in
1)
echo "option 1"
echo;;
2)
echo "option 2"
echo;;
3)
echo "option 3"
echo;;
q) echo -e "\033[01;33mexit!!!\033[39m"
sleep 1
clear
exit ;;
*)
echo "Unknown command"
read -s -n 1 -p "Press any key to continue…"
echo
esac
}
while:
do function
done
The above works fine, but need to press enter after I input the number before the command run. Is there any way to immediately run the command when I press the key?
You've got the answer right in your sample code (in the second read). You want to take advantage of bash's read -n 1 capability (note, this is not POSIX compliant, so it won't reliably work in /bin/sh unless that happens to map to bash):
read -n 1 -p "Select 1-3 ή \"q\" to quit: " i
so I am trying to create a script which gives the user some options to do things, one of that option is to exit the script. However, I want to prevent the user from exiting the script using Control c so that the only way to exit is to select the right option. Is it possible to make the script so that when the user hits control c, the program will not exit, but rather it would echo something like "enter 0 to exit"?
#!/bin/bash
# Acts as a simple administration menu
OPTION=0
echo "-----------------Admin Menu-------------------"
echo "Please select one of the following options: "
echo ""
echo "1 - Run top."
echo "2 - Show system uptime."
echo "3 - Show logged in users."
echo "4 - Exit Menu."
echo "5 - Reprint this menu."
echo "----------------------------------------------"
echo "Please choose an option (5 to reprint menu):"
read OPTION
while [ "$OPTION" -ne 4 ]
do
if [ "$OPTION" -eq 1 ]; then
clear
top -n1
elif [ "$OPTION" -eq 2 ]; then
clear
uptime
elif [ "$OPTION" -eq 3 ]; then
clear
who
elif [ "$OPTION" -eq 4 ]; then
clear
OPTION=4
elif [ "$OPTION" -eq 5 ]; then
clear
echo "------------COSC 2306 Admin Menu--------------"
echo "Please select one of the following options: "
echo ""
echo "1 - Run top."
echo "2 - Show system uptime."
echo "3 - Show logged in users."
echo "4 - Exit Menu."
echo "5 - Reprint this menu."
echo "----------------------------------------------"
else
clear
echo "ERROR: Incorrect Input."
fi
echo "Please choose an option (5 to reprint menu):"
read OPTION
done
clear
You can use the trap built-in to catch SIGINT ( ctrl + C generates the signal SIGINT) and print your message:
trap 'echo "enter 0 to exit"' SIGINT
Similarly you can catch other signals too. To get the list of signals use kill -l.