Save file content from editbox in BASH - 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

Related

Dialog --menu open another --menu bash

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

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 :).

validate for empty string including a space linux

DIALOG=${DIALOG=dialog}
tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$
trap "rm -f $tempfile" 0 1 2 5 15
$DIALOG --backtitle "Search Forename" --inputbox \
"Please enter your Forename?" 0 0 2> /tmp/inputbox.tmp.$$
retval=$?
Forename=`cat /tmp/inputbox.tmp.$$`
case $retval in
0)
while [[ $Forename = "" ]]; do
$DIALOG --msgbox "Forename Cannot be left blank" 10 40;
$DIALOG --backtitle "Search Forename" --inputbox \
"Please enter your Forename?" 0 0 2> /tmp/inputbox.tmp.$$
retval=$?
Forename=`cat /tmp/inputbox.tmp.$$`
rm -f /tmp/inputbox.tmp.$$
done
Forename=$(echo $Forename | tr 'a-z' 'A-Z');
echo;
if ! grep -Fq "Forename: $Forename" $Filename ;then
$DIALOG --msgbox "$Forename was not found in the File" 10 40;
else
$DIALOG --title "Forename Results" --infobox "`grep -n "Forename: $Forename" $Filename | sort ;`" 90 120 ;
read enterKey;
fi
;;
1)
echo "Cancel pressed.";;
esac
;;
the problem I am having is that the forename only validates for being empty if the user enters a space it displays all the data in the file. Could anyone suggest a way to fix this. Any help is much appreciated.
You can use bash's regex syntax.
while [[ -z $Forename || $Forename =~ ^\ +$ ]]; do
# if forename is empty or contains only whitespace
...
done

How can I store edited text file using bash?

This is my code:
Edit_Record() {
zenity --width=600 --height=300 --text-info --title="Records" --filename=$FILE --editable
if [ "$?" = 0 ]; then
kdialog --title "Saving the Data" --warningyesnocancel "Do you want to save the changes?"
if [ "$?" = 0 ]; then
kdialog --msgbox "The changes have been added!"
Home;
elif [ "$?" = 1 ]; then
kdialog --msgbox "No changes has been added!"
Home;
else
Home;
fi;
else
zenity --info --text "You chose to Cancel."
exit
fi;
}
I dont know what to put behind "kdialog --msgbox "The changes have been added!" :(
Help please?
zenity --editable returns the edited text to standard output. You can save it to a temporary file by redirection, and if the user wants to save the changes, just move the temporary file over the original.
tmp=$(mktemp)
zenity --editable ... > $tmp
if ... ; then
mv $FILE "$FILE"~
mv $tmp "$FILE"
fi

Resources