How can I store edited text file using bash? - 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

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

How do I print the selected column?

I want to echo the currently selected list when i press a button, but all it does is run the function i assign to the button. I want it to detect if a list was selected, if not show another yad window saying "Please select a Task/Reminder to use this button!", but if something was selected display a yad window saying "You selected: List name List date" Thanks.
#!/bin/bash
DIRECTORY="$(readlink -f "$(dirname "$(dirname "$0")")")"
AppName="$(cat $DIRECTORY/data/info/appname.inf)"
Used="$(cat $DIRECTORY/data/info/opd)"
#load functions
source "${DIRECTORY}/scripts/functions" || error "failed to source ${DIRECTORY}/scripts/functions"
#Display MainMenu if program has been used before.
if [ $Used == "True" ]; then
#Display Tasks/Reminders if there are any
if [ -d "$DIRECTORY/Tasks" ]; then
while IFS='|' read -r Name Date _; do
if [[ $Name || $Date ]]; then
items+=( "$Name" "$Date" )
else
items+=( "None" "None" )
fi
done < <(sort -t'|' -k2 $DIRECTORY/Tasks/Tasks.txt)
yad --separator='\n' --title="$AppName" --window-icon="${DIRECTORY}/icons/logo.png" --center --width='300' --height='300' --text-align="center" --text="Welcome to $AppName! \nWhat would you like to do?" --button="Add new Task/Reminder"!"${DIRECTORY}/icons/install.png"!'Create a new Task/Reminder':2 --button="Delete Task/Reminder"!"${DIRECTORY}/icons/uninstall.png"!'Delete Task/Reminder':3 --list --column=Task/Reminder "${items[0]}" --column=Date "${items[1]}"
else
yad --separator='\n' --title="$AppName" --window-icon="${DIRECTORY}/icons/logo.png" --center --width='300' --height='100' --text-align="center" --text="Welcome to $AppName! \nWhat would you like to do?" --button="Add new Task/Reminder"!"${DIRECTORY}/icons/install.png"!'Create a new Task/Reminder':2
fi
else #Display StartupMenu.
yad --separator='\n' --title="$AppName" --window-icon="${DIRECTORY}/icons/logo.png" --center --width='300' --height='300' --text-align="center" --text="Thanks for instaling $AppName! \nClick next to learn how to use $AppName." --window-icon="${DIRECTORY}/icons/logo.png" --button=Cancel!"${DIRECTORY}/icons/exit.png"!'Exit':0 --button='Next'!"${DIRECTORY}/icons/forward.png"!'Continue.':1
fi
button=$? #get exit code to determine which button was pressed.
if [ $button -eq 0 ];then
echo "True" > $DIRECTORY/data/info/opd
elif [ $button -eq 1 ];then
bash "$DIRECTORY/scripts/firstrun/learn"
elif [ $button -eq 2 ];then
nameofnew="$(yad --entry --window-icon="${DIRECTORY}/icons/logo.png" --separator='\n' --title="Create a new Task/Reminder" --center --text-align="center" --entry-label="Name of new Task/Reminder:")"
selecteddate="$(yad --calendar --window-icon="${DIRECTORY}/icons/logo.png" --title="Select a date" --height="200" --width="400")"
yad --separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" --title="Is this correct?" --center --width='300' --height='300' --text-align="center" --text="Is this correct? \nName of Task/Reminder: '$nameofnew'\nSelected date for new Task/Reminder: '$selecteddate'" --button="No"!"${DIRECTORY}/icons/exit.png"!'No':2 --button='Yes'!"${DIRECTORY}/icons/check.png"!'yes':3
elif [ $button -eq 3 ];then
if [ -d "$DIRECTORY/Tasks" ]; then
yad
else
g
fi
elif [ $button -eq 252 ];then
exit 0
else
error "Unkown button input recived: $button"
fi
All I had to do was store the yad window as a variable; then, I could get the selected list.
option="$(yad --separator='\n' --title="$AppName" --window-icon="${DIRECTORY}/icons/logo.png" --center --width='300' --height='300' --text-align="center" --text="Welcome to $AppName! \nWhat would you like to do?" --button="Add new Task/Reminder"!"${DIRECTORY}/icons/install.png"!'Create a new Task/Reminder':2 --button="Delete Task/Reminder"!"${DIRECTORY}/icons/uninstall.png"!'Delete Task/Reminder':3 --list --column=Task/Reminder "${items[0]}" --column=Date "${items[1]}")"
echo $option
if [ "$option" -eq "" ]; then
yad --title="Error" --text="You didn't select a Task/Reminder! Please go back and try again"
else
# Do something with the selected items.
fi

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
}

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

Bash Backup Script Progress Bar

I am creating a bash script that will backup a directory specified by the user. At the moment when the program runs the user will see all the files on the screen being compressed and copied, is there a while to simply replace what the user sees with a simple progress bar?
#!/bin/bash
ROOT="/Users/Rory/Documents"
ROOT_EXCLUDE="--exclude=/dev --exclude=/proc --exclude=/sys --exclude=/temp --exclude=/run --exlucde=/mnt --exlcude=/media --exlude"
DESTIN="/USer/Rory/Documents"
if [ "$USER" != "root" ]; then
echo "You are not the root user"
echo "To use backup please use: sudo backup"
exit
fi
clear
BANNER1="************************************************"
BANNER2="********* Backup Menu **************************"
BANNER3 ="************************************************"
echo $BANNER1
echo $BANNER2
echo $BANNER3
echo $BANNER3
OPTIONS="BACKUP DESTINATION EXIT"
LIST="1)BACKUP 2)SET DESTINATION 3)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
clear
exit
elif [ "$opt" = "BACKUP" ]; then
echo "BACKING UP FILES..."
tar cvpfz $DESTIN/backup.`date +%d%m%y_%k%M`.tgz $ROOT $ROOT_EXCLUDE_DIRS
echo "BACKUP COMPLETE"
exit
elif [ "$opt" = "DESTINATION"]; then
echo "DESTINATION IS $DESTIN/backup.`date +%d%m%y_%k%M`.tgz "
echo "TO CHANGE ENTER THE NEW DESTINATION..."
echo "TO LEAVE IT AS IS JUST PRESS ENTER..."
read NEW_DESTIN
#IF GREATER THEN 0 ASSIGN NEW DESTINATION
if [ ${#NEW_DESTIN} -gt 0 ]; then
DESTIN = "$NEW_DESTIN"
fi
clear
echo $BANNER1
echo $BANNER2
echo $BANNER3
echo $LIST
else
clear
echo "BAD INPUT!"
echo "ENTER 1 OR 2..."
echo $LIST
fi
done
If you copy your files using rsync, you can get a progress bar using the --progress parameter.
rsync --progress ...

Resources