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
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
I have this script:
#!/bin/bash
menu()
{
while true; do
opt=$(whiptail \
--title "Select an item" \
--menu "" 20 70 10 \
"1 :" "Apple" \
"2 :" "Banana" \
"3 :" "Cherry" \
"4 :" "Pear" \
3>&1 1>&2 2>&3)
rc=$?
echo "rc=$rc opt=$opt"
if [ $rc -eq 255 ]; then # ESC
echo "ESC"
return
elif [ $rc -eq 0 ]; then # Select/Enter
case "$opt" in
1\ *) echo "You like apples"; return ;;
2\ *) echo "You go for bananas"; return ;;
3\ *) echo "I like cherries too"; return ;;
4\ *) echo "Pears are delicious"; return ;;
*) echo "This is an invalid choice"; return ;;
esac
elif [ $rc -eq 1 ]; then # Cancel
echo "Cancel"
return
fi
done
}
menu
When I press ESC button, the output is as expected:
rc=255 opt=
ESC
Now, by making opt a local variable, the behaviour is different:
...
local opt=$(whiptail \
...
Output:
rc=0 opt=
This is an invalid choice
Can someone explain this?
$? is getting the return code of the local command. Try making the local command and the assignment separate statements:
local opt
opt=$(whiptail ...
I found this wonderful tool to check a bash script for possible bugs...
$ shellcheck myscript
Line 6:
local opt=$(whiptail \
^-- SC2155: Declare and assign separately to avoid masking return values.
$
This is what I have so far and it works in the sense that it give a gauge and I can pass it as many commands as I want. The problem is the $COMMAND never actually executes on the shell.
#!/bin/bash
progressBar() {
declare TODO=("${#}")
NUM_TODO=${#TODO[*]}
STEP=$((100/NUM_TODO))
IDX=0
COUNTER=0
(
while :
do
cat <<EOF
XXX
$COUNTER
${TODO[$IDX]}
XXX
EOF
COMMAND="${TODO[$IDX]} &>/dev/null"
[[ $NUM_TODO -lt $IDX ]] && $COMMAND
(( IDX+=1 ))
(( COUNTER+=STEP ))
[ $COUNTER -gt 100 ] && break
sleep 1
done
) |
whiptail --title "Please wait..." --gauge "Please wait..." 6 70 0
}
progressBar \
"touch bla" \
"cp bla bla-`date +%Y%m%d%H%M`.backup"
I think [[ $NUM_TODO -lt $IDX ]] is round the wrong way, should be $IDX -lt $NUM_TODO.
I am dealing with sorting words in Bash according to a given argument. I am given either argument -r, -a , -v or -h and according to it there are options to sort the words, as you can see at my "help".
Somehow, if I pass the argument -r it creates an error. I really don't understand what I am doing wrong, as if[["$arg"=="-a"]] works, but I have to use case somehow.
Here is my code:
#!/bin/bash
# Natalie Zubkova , zubkonat
# zubkonat#cvut.fel.cz , LS
#help
help="This script will calculate occurances of words in a given file, and it will sort them according to the given argument in following order> \n
without parametre = increasing order according to a number of occurance\n
-r = decreasing order according to a number of occurance\n
-a = in alphabetical increasing order\n
-a -r = in alphabetical decreasing order\n
There are also special cases of the given parametre, when the script is not sorting but:\n
-h = for obtaining help \n
-v = for obtaining a number of this task "
# this function will divide a given chain into a words, so we can start calculating the occurances, we also convert all the capital letters to the small ones by - tr
a=0;
r=0;
EXT=0;
if [ "$1" == "-h" ]; then
echo $help
exit 0
fi
if [ "$2" == "-h" ]; then
echo $help
exit 0
fi
if [ "$1" == "-v" ]; then
echo "5"
exit 0
fi
if [ "$2" == "-v" ]; then
echo "5"
exit 0
fi
function swap {
while read x y; do
echo "$y" "$x";
done
}
function clearAll {
sed -e 's/[^a-z]/\n/gI' | tr '[A-Z]' '[a-z]' | sort | uniq -c |awk '{i++; if(i!=1) print $2" "$1}' #swap
}
for arg do
case "$arg" in
"-a")
a=1
;;
"-r")
r=1
;;
"-v")
echo "5" #number of task is 5
exit 0
;;
"-h")
echo $help
exit 0
;;
"-?")
echo "invalid parametre, please display a help using argument h"
exit 0
;;
esac
done
#Sort according to parametres -a and -r
function sortWords {
if [[ a -eq 1 ]]; then
if [[ r -eq 0 ]]; then
clearAll | sort -nk1
fi
fi
if [[ a -eq 1 ]]; then
if [[ r -eq 1 ]]; then
clearAll | sort -nk1 -r
fi
fi
if [[ r -eq 1 ]]; then
if [[ a -eq 0 ]]; then
clearAll | sort -nk2 -r
fi
fi
if [[ a -eq 0 ]]; then
if [[ r -eq 0 ]]; then
clearAll | sort -nk2
fi
fi
}
#code is from Stackoverflow.com
function cat-all {
while IFS= read -r file
do
if [[ ! -z "$file" ]]; then
cat "$file"
fi
done
}
#histogram
hist=""
for arg do
if [[ ! -e "$arg" ]]; then
EXT=1;
echo "A FILE DOESNT EXIST" >&2
continue;
elif [[ ! -f "$arg" ]]; then
EXT=1;
echo "A FILE DOESNT EXIST" >&2
continue;
elif [[ ! -r "$arg" ]]; then
EXT=1;
echo "A FILE DOESNT EXIST" >&2
continue;
fi
done
for arg do
hist="$hist""$arg""\n"
done
echo -e "$hist" | cat-all | sortWords
exit $EXT;
Here is what our upload system which does some test to see if our program works says:
Test #6
> b5.sh -r ./easy.txt
ERROR: script output is wrong:
--- expected output
+++ script stdout
## --- line 1 (167 lines) ; +++ no lines ##
-the 89
-steam 46
-a 39
-of 37
-to 35
...
script written 484 lines, while 484 lines are expected
script error output:
A FILE DOESNT EXIST
cat: invalid option -- 'r'
Try `cat --help' for more information.
script exit value: 1
ERROR: Interrupted due to failed test
If anyone could help me I would really appreciate it.
You forgot to move the parameter index position with shift:
"-r")
r=1
shift
;;
shift above moves to the next command line arg: ./easy.txt in your case.
Without it, read -r file will read -r instead of the file name.