Scripting using Zenity GUI - bash

I try to make a script bash app with the help of Zenity.
https://help.gnome.org/users/zenity/stable/index.html.en
It works properly, however I encounter a problem ...
Here is my code:
#!/bin/bash
APP_NAME="bealeCrypter"
function select_letter () {
letter=("FALSE" "1" "Treasury location" "none"
"FALSE" "2" "Treasury contents" "yes"
"FALSE" "3" "Treasury beneficiaries" "none")
LETTER_FILES=$(zenity --list \
--width=430 \
--height=235 \
--title="$APP_NAME" \
--text="What letter do you want to $1 ?" \
--checklist \
--multiple \
--column=Selection \
--column=Letter \
--column=Description \
--column=Decrypted \
"${letter[#]}")
if [ $? -eq 0 ]; then
if [ -z "$LETTER_FILES" ]; then
select_letter "$1"
fi
else
app_main
fi
}
function select_letter_options () {
letter_options=("TRUE" "1" "Get the number of characters"
"TRUE" "2" "Get the smallest number"
"TRUE" "3" "Get the biggest number")
LETTER_OPTIONS=$(zenity --list \
--width=350 \
--height=210 \
--hide-header \
--title="$APP_NAME" \
--text="Choose the analyze letter options :" \
--checklist \
--multiple \
--column=Selection \
--column=Id \
--column=Description \
--hide-column=2 \
"${letter_options[#]}")
if [ $? -eq 0 ]; then
if [ -z "$LETTER_OPTIONS" ]; then
select_letter_options
fi
else
app_main
fi
}
function app_main () {
menu=("1" "Analyze a Letter")
SELECTION=$(zenity --list \
--width=350 \
--height=210 \
--hide-header \
--title="$APP_NAME" \
--text="What to do ?" \
--column=Id \
--column=Selection \
--hide-column=1 \
--cancel-label=Quit \
"${menu[#]}")
if [ $? -eq 0 ]; then
case "$SELECTION" in
1) select_letter "analyze"
select_letter_options
;;
*) app_main
esac
echo -e "LETTER: $LETTER_FILES\nKEY: $KEY_FILES\nLETTER_OPTIONS: $LETTER_OPTIONS\nKEY_OPTIONS: $KEY_OPTIONS"
else
exit 0
fi
}
app_main
Here is my problem, When I select the following menus/button (in this specific order):
Analyze a Letter
Cancel
Analyze a Letter
Select checkbox 1, 2 or 3 and OK
Select options and OK
the option window opens twice after the validation OK, I don't understand why?
Here is a video demo:
https://streamable.com/np7wzl
I specify that if I do not make a Cancel (point #2) it works correctly.
How is it possible?
I tried to empty the variables before recalling the function but the result and always identical, I do not understand?
Does anyone have an explanation for this?

Related

Zenity file selection displaying

so im trying to do a delete function inside zenity . I managed to let the user input his desired path and then i want to display all the files that are present inside it . I found out how to do it and i know it work but no with zenity . The next window (file selection) is not poping up and my program get back to the menu. thanks here is my code.Thanks u for your help and time!
#!/bin/bash
function Ddate()
{
zenity --info \
--title "Date and Time" \
--text "Today is $(date)"
}
function Dcalendar()
{
zenity --forms \
--title "Scheduler" \
--text "Pick a date" \
--add-calendar "Calendar" \
--add-entry "Reminder"
}
function Ddelete()
{
directory=$(zenity --entry \
--text "Enter a path" \
--title "Delete" )
if [ -z "$directory" ];then
directory=$ pwd
else
if [ -d "$directory" ];then
zenity --file-selection --filename=$(directory)
fi
fi
}
while true;
do
choice="$(zenity --height 275 --width 450 \
--list \
--title="" \
--column="Function" --column="Description" \
Date 'Display the actual date and time.' \
Calendar 'Display an interactive calendar.' \
Delete 'Let you delete a file.' \
Exit 'To quit this script.')"
case $choice in
Date) Ddate;;
Calendar) Dcalendar;;
Delete) Ddelete;;
Exit) break;;
esac
done
To fix my problem, i understand the meaning behind the $? escape code . In each window $? control the ok and cancel button taking value 0 and 1 respectively.
Inside my program I cleared the $? first because of the previous window , a value can be already set in, and set a variable ret to $? meaning if someone press ok or cancel it continue to the next window or goes back to the root window.
function Ddelete()
{
directory=$(zenity --entry \
--text "Enter a path" \
--title "Delete" )
if [ -z "$directory" ];then
directory=$ pwd
else
if [ -d "$directory" ];then
clear $?
Spath=$(zenity --file-selection --filename=$(directory))
ret=$?
fi
fi
}

Bash - Show dialog infobox while operation

I'm scripting in bash for the first time. I'll crating a menu with dialog and add some function. I like to show a --infobox during a operation is running, so the user see something is happening.
The target is to have a dialogbox like
dialog --infobox "Please wait" 10 30
while the script is making the ping. If the ping is done, the --msgbox dialog opens.
test_rtt() {
ipSlave=$(awk '{ if($1~/'$SETSLAVE'/) print $2 }' $VARPATH/$VARCONFIGFILE)
pingSlave=$(fping -c1 -t300 $ipSlave 2>/dev/null 1>/dev/null)
if ! [ "$?" = 0 ]
then
result="Loopbox (Slave) not found on $ipSlave"
dialog \
--backtitle "$VARBACKTITLE" \
--title "$1" \
--no-collapse \
--msgbox "$result" $VARMENUHEIGHT $VARMENUWIDTH
fi
nrtest=$(awk '{ if($1~/'$SETNRTEST'/) print $2 }' $VARPATH/$VARCONFIGFILE)
intervl=$(awk '{ if($1~/'$SETINTERVL'/) print $2 }' $VARPATH/$VARCONFIGFILE)
result=$(ping -c $nrtest -i $intervl -U 192.168.74.93 | tail -1) #(HERE I WANT THE INFOBOX)
dialog \
--backtitle "$VARBACKTITLE" \
--title "$1" \
--no-collapse \
--msgbox "$result" $VARMENUHEIGHT $VARMENUWIDTH
}
If I get you correctly, you want to give the user the signal that "something is happening". I made two solutions. You can play with them.
The first one print the information before executing $(fping..
The second one uses dialog --progressbox to make progress box that is visible for the user.
I modified your code, so it pings 8.8.8.8 and checks if it's available.
#!/bin/bash
test_rtt() {
dialog --infobox "Please wait" 10 30
pingSlave=$(fping -c5 -t300 8.8.8.8 2>/dev/null 1>/dev/null)
# What is reason for introducing pingSlave var :)?
if [ "$?" = 0 ]
then
result="Ping succeed for 8.8.8.8"
dialog \
--backtitle "test1" \
--title "test2" \
--no-collapse \
--msgbox "$result" 50 50
fi
}
test_rtt_2() {
fping -c5 -t300 8.8.8.8 | dialog --progressbox 50 50
if [ "$?" = 0 ]
then
result="Ping succeed for 8.8.8.8"
dialog \
--backtitle "test1" \
--title "test2" \
--no-collapse \
--msgbox "$result" 50 50
fi
}
test_rtt
dialog --clear
test_rtt_2
dialog --clear
I hope that this is what you expected :).

Bash Back to run script

i want to make an config script.
The main Script starts with "start.sh"
If the Script starts i can choose "install" "update" etc.
Now i want add "Config" and add content like php congigs like upload size....
But how i can go back to the start.sh? I want use parent id but im not sure how i can make it correct.
Start.sh
1.2 > Config
1.3 >> runs php_config.sh"
Now i want go back to "Start.sh" without run "start.sh" again. The vars i change would be written in a file and are global readable from start.sh > installer
Thank oyu
Edit: Sorry for bad quick asking...
i start the start.sh and install dialog and make a menu.
If the user choose "Make 2" i load the file and start the function.
#!/bin/bash
#-------------dialog
apt-get -qq install dialog >/dev/null 2>&1
HEIGHT=30
WIDTH=60
CHOICE_HEIGHT=14
BACKTITLE="How to get back"
TITLE="Back"
MENU="Choose one of the following options:"
OPTIONS=(1 "Make 1"
2 "Make 2"
3 "Make 3")
CHOICE=$(dialog --clear \
--nocancel \
--no-cancel \
--backtitle "$BACKTITLE" \
--title "$TITLE" \
--menu "$MENU" \
$HEIGHT $WIDTH $CHOICE_HEIGHT \
"${OPTIONS[#]}" \
2>&1 >/dev/tty)
clear
case $CHOICE in
1)
# Make 1
;;
1)
# Make 2
source ${SCRIPT_PATH}/menu_php_7_x.sh; php_7_x_config
;;
1)
# Make 3
;;
esac
The menu_php_7_x.sh is like this:
#!/bin/bash
php_7_x_config() {
HEIGHT=30
WIDTH=60
CHOICE_HEIGHT=6
BACKTITLE="config php"
TITLE="Choose php.ini config"
MENU="Choose one of the following options:"
OPTIONS=(1 "Change post_max_size"
2 "Change upload_max_filesize"
3 "Change memory_limit"
)
CHOICE=$(dialog --clear \
--nocancel \
--no-cancel \
--backtitle "$BACKTITLE" \
--title "$TITLE" \
--menu "$MENU" \
$HEIGHT $WIDTH $CHOICE_HEIGHT \
"${OPTIONS[#]}" \
2>&1 >/dev/tty)
clear
case $CHOICE in
1)
CHOICE_HEIGHT=2
MENU="Change post_max_size"
post_max_size=$(dialog --clear \
--backtitle "$BACKTITLE" \
--inputbox "Please Type your post_max_size value:" \
$HEIGHT $WIDTH \
3>&1 1>&2 2>&3 3>&- \
)
;;
2)
CHOICE_HEIGHT=2
MENU="Change upload_max_filesize"
upload_max_filesize=$(dialog --clear \
--backtitle "$BACKTITLE" \
--inputbox "Please Type your upload_max_filesize value:" \
$HEIGHT $WIDTH \
3>&1 1>&2 2>&3 3>&- \
)
;;
3)
CHOICE_HEIGHT=2
MENU="Change memory_limit"
memory_limit=$(dialog --clear \
--backtitle "$BACKTITLE" \
--inputbox "Please Type your memory_limit value:" \
$HEIGHT $WIDTH \
3>&1 1>&2 2>&3 3>&- \
)
;;
esac
# Back to menu
start.sh
}
This is only an example i want make the config with more options and pre selections or the user have choose from selection and have not input a value.
My questions is now how i can go back to the script to let the user runs installation.

Save file content from editbox in BASH

I want to learn shell-scripting. I want to create simple tool to show file content with edit option but I can't get value from dialog --editbox. Anybody can explain me how it works?
My code:
#!/bin/bash
BACKTITLE="Some backtitle"
FILENAME="filename.txt"
touch $FILENAME
INPUT=/tmp/menu.sh.$$
ret=0
while [ $ret -eq 0 ]
do
dialog --title "Menu" \
--backtitle "$BACKTITLE" \
--menu "Wybierz" 10 60 3 \
1 "Pokaz menu" \
2 "Edytuj" \
2>"${INPUT}"
ret=$?
option=$(<"${INPUT}")
if [ $ret -eq 0 ]
then
if [ $option -eq 1 ]
then
dialog --title "File content" \
--backtitle "$BACKTITLE" \
--textbox $FILENAME 10 60
elif [ $option -eq 2 ]
then
dialog --title "Edit file content" \
--backtitle "$BACKTITLE" \
--editbox $FILENAME 10 60
editboxret=$?
echo $editboxret
ret=0
fi
fi
done
Per the manpage (man dialog), the output is written to stderr.
Using the suggestion in https://stackoverflow.com/a/6317938/5528982, you can use
{ newcontents=$(dialog --title "Edit file content" -- backtitle "$BACKTITLE" --editbox $FILENAME 10 60 2>&1 1>&$out); } {out}>&1
dialog writes the 'edited' content to STDERR you need to make sure it ends up in the original file again.
# Write the output of dialog to a temp-file
dialog --editbox $FILENAME 10 60 2> "${INPUT}"
# ADVISED: Show the user the temporary file-content
# and ask for confirmation before doing the next step:
# Overwrite the input-file
cp ${INPUT} $FILENAME

Makefile Substituting for loop variables to functions

I'm not sure what the best way to do this, and some pointers in this regard would be helpful
Code:
#Else where in different file and included in this makefile i have
LIBRARY_LIST := CONFIG_MTS_PTHREADS
CONFIG_MTS_PTHREADS := y
collect-compilation:
if [ $(strip $(CONFIG_MTS_PTHREADS)) == y ]; then \
echo "ok"; \
fi;
for compile in $(LIBRARY_LIST) ; do \
if [ $(strip $$compile) == y ]; then \
echo "ok"; \
fi; \
done
So from the above code snippet., the top part the 'IF' loop works fine as expected and i see 'OK'.
displayed.
Now for the second for-loop, i have some problems substituting the $$compile to the 'IF'. Eventually i expect $$compile gets replaced by CONFIG_MTS_PTHREADS and the expression should evaluate to y == y and display 'OK' but for me.,
Output:
make -C ./Dev2.0.1/OSX
if [ y == y ]; then \
echo "ok"; \
fi;
ok <----- fine and expected
for compile in CONFIG_MTS_PTHREADS ; do \
if [ $compile == y ]; then \
echo "ok"; \
fi; \
done <------ Here it skips the then part and proceeds further, i expect 'OK' after this though.
The trouble is that you're mixing Make-expansion and shell-expansion.
We start with this command:
for compile in $(LIBRARY_LIST) ; do \
if [ $(strip $$compile) == y ]; then \
echo "ok"; \
fi; \
done
Make expands the variables:
for compile in CONFIG_MTS_PTHREADS ; do \
if [ $compile == y ]; then \
echo "ok"; \
fi; \
done
(note that compile has no value yet) and passes the command to the shell, which expands the variables, runs the for loop and winds up testing:
if [ CONFIG_MTS_PTHREADS == y ]; then
which clearly must fail. It is too late to expand CONFIG_MTS_PTHREADS; the shell doesn't know that it's a variable with a value. Make knew, but Make has already handed to command off to the shell.
One solution is to use the value function, so that Make will expand the variable before passing it to the shell:
for compile in $(value $(LIBRARY_LIST)) ; do \
if [ $(strip $$compile) == y ]; then \
echo "ok"; \
fi; \
done

Resources