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
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
#!/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.
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
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
I am trying to make an application for the Mac App Store that will shut down/sleep the Mac after a user-set time. I have tried to use AppleScript, but that won't work if I am going to use it in Sandbox mode, I have tried to Google for a solution, but I cant seem to figure it out.
Hope someone can give me a hint or link to relevant documentation.
edit: made it more precise to what I desire to accomplish.
There is no way to do this. You may try to get a temporary-exception to run "shutdown" or "halt" thru BSD-layer but I doubt that such an app will pass the App Store review as these are tasks that require superuser / admin rights.
I wrote a script once. But I don't know whether it still works. Maybe it gives you at least a clue. Sleep still works - shutdown maybe causes problems if programs are blocking the shutdown.
(Not the prettiest code but it worked for me.)
#/bin/sh
#v1.0.0
#by Sapphire
echo "-----------------------------------------------------"
echo "* Sleep Timer *"
echo "-----------------------------------------------------"
echo "Please enter option: Sleep '1' or shutdown '0'"
echo -n "Option: "
read option
while :
do
if [ $option -eq 1 -o $option -eq 0 ]
then
break
fi
echo "<<ERROR: Only number: 1 or 0 allowed...>>"
echo "Please rnter option: Sleep '1' or shutdown '0'"
echo -n "Option: "
read option
done
echo "Please enter countdown (min):"
echo -n "Minutes: "
read shutDown
while :
do
if [ $shutDown -gt 0 -a $var -eq $var 2> /dev/null ]
then
break
fi
echo "<<ERROR: Positive number expected...>>"
echo "Please enter countdown (min):"
echo -n "Minutes: "
read shutDown
done
echo "*****************************************************"
echo "Counter has been started"
echo "'/!\ Kill countdown with CTRL-C /!\'"
echo -n "Envoking command in: "
date +"%H:%M %Z"
echo "*****************************************************"
if [ $option -eq 0 ]
then
echo "Shutdown in: "
fi
if [ $option -eq 1 ]
then
echo "Sleep in: "
fi
echo -e "\n *------------------------------* "
barCounter=0;
counter=0
((timeBarSize=$shutDown * 2))
bar="||||||||||||||||||||||||||||||"
barEmpty=" "
((flag=0))
for ((i=shutDown*60;i>=0;i--));
do
if ((counter >= timeBarSize ))
then
((counter=0))
((barCounter=$barCounter + 1))
fi
((counter=$counter + 1))
((timehh=$i/3600))
((timemm=$i/60 - timehh*60))
((timess=$i - timemm*60 - timehh*3600))
if (( flag == 1 ))
then
echo $(tput cuu1)$(tput el)$(tput cuu1)$(tput el)$(tput cuu1)$(tput el)$(tput cuu1)$(tput el)$(tput cuu1)
fi
((flag=1))
echo -e " | $timehh:$timemm:$timess |"
echo -e "\r *------------------------------* "
echo -e "\r *${bar:0:$barCounter}${barEmpty:$barCounter:30}* "
echo -e "\r *------------------------------* "
sleep 1;
done
if [ $option -eq 1 ]
then
echo "Going to sleep..."
sleep 1
osascript -e 'tell application "System Events" to sleep'
elif [ $option -eq 0 ];
then
echo "Shutting down..."
sleep 1
osascript -e 'tell application "System Events" to shut down'
else
echo "No valid command found... doing nothing!"
fi
I also had to add this in my '/etc/sudoers' file (CAUTION, if you don't know how to handle this file! -> google):
# Custom privilege
myUser ALL=NOPASSWD: /Users/myUser/Documents/sleepTimer.sh