How do I print the selected column? - bash

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

Related

How can I make this multi-select Bash script default to all items selected?

I modified a great script I found online by Nathan Davieau on serverfault.com, but I have hit the limit to my knowledge of Bash!
It works great, apart from I have to select each item, I want it to start with all items selected and have to deselect them.
#!/bin/bash
ERROR=" "
declare -a install
declare -a options=('php' 'phpmyadmin' 'php-mysqlnd' 'php-opcache' 'mariadb-server' 'sendmail')
#=== FUNCTION ========================================================================
# NAME: ACTIONS
# DESCRIPTION: Actions to take based on selection
# PARAMETER 1:
#=======================================================================================
function ACTIONS() {
for ((i = 0; i < ${#options[*]}; i++)); do
if [[ "${choices[i]}" == "+" ]]; then
install+=(${options[i]})
fi
done
echo "${install[#]}"
}
#=== FUNCTION ========================================================================
# NAME: MENU
# DESCRIPTION: Ask for user input to toggle the name of the plugins to be installed
# PARAMETER 1:
#=======================================================================================
function MENU() {
echo "Which packages would you like to be installed?"
echo
for NUM in "${!options[#]}"; do
echo "[""${choices[NUM]:- }""]" $((NUM + 1))") ${options[NUM]}"
done
echo "$ERROR"
}
#Clear screen for menu
clear
#Menu loop
while MENU && read -e -p "Select the desired options using their number (again to uncheck, ENTER when done): " -n2 SELECTION && [[ -n "$SELECTION" ]]; do
clear
if [[ "$SELECTION" == *[[:digit:]]* && $SELECTION -ge 1 && $SELECTION -le ${#options[#]} ]]; then
((SELECTION--))
if [[ "${choices[SELECTION]}" == "+" ]]; then
choices[SELECTION]=""
else
choices[SELECTION]="+"
fi
ERROR=" "
else
ERROR="Invalid option: $SELECTION"
fi
done
ACTIONS
Here you go, you only need to initialize the choices[] (array) before you actually process them. (re-)Revised code below (with thanks to Charles Duffy) :
#!/bin/bash
ERROR=" "
declare -a install
declare -a options=('php' 'phpmyadmin' 'php-mysqlnd' 'php-opcache' 'mariadb-server' 'sendmail')
############### HERE's THE NEW BIT #################
declare -a choices=( "${options[#]//*/+}" )
####################################################
#=== FUNCTION ========================================================================
# NAME: ACTIONS
# DESCRIPTION: Actions to take based on selection
# PARAMETER 1:
#=======================================================================================
function ACTIONS() {
for ((i = 0; i < ${#options[*]}; i++)); do
if [[ "${choices[i]}" == "+" ]]; then
install+=(${options[i]})
fi
done
echo "${install[#]}"
}
#=== FUNCTION ========================================================================
# NAME: MENU
# DESCRIPTION: Ask for user input to toggle the name of the plugins to be installed
# PARAMETER 1:
#=======================================================================================
function MENU() {
echo "Which packages would you like to be installed?"
echo
for NUM in "${!options[#]}"; do
echo "[""${choices[NUM]:- }""]" $((NUM + 1))") ${options[NUM]}"
done
echo "$ERROR"
}
#Clear screen for menu
clear
#Menu loop
while MENU && read -e -p "Select the desired options using their number (again to uncheck, ENTER when done): " -n2 SELECTION && [[ -n "$SELECTION" ]]; do
clear
if [[ "$SELECTION" == *[[:digit:]]* && $SELECTION -ge 1 && $SELECTION -le ${#options[#]} ]]; then
((SELECTION--))
if [[ "${choices[SELECTION]}" == "+" ]]; then
choices[SELECTION]=""
else
choices[SELECTION]="+"
fi
ERROR=" "
else
ERROR="Invalid option: $SELECTION"
fi
done
ACTIONS
Sorry, but I can't afford the time to give a blow by blow description of how all this works. In this case, the traditional shell debugging tool of set -vx (paired with set +vx) might be a challenge to interpret for a newbie. Experiment only when you can spare the time.
Note that the key bit of code is where the + gets toggled :
if [[ "${choices[SELECTION]}" == "+" ]]; then
choices[SELECTION]=""
else
choices[SELECTION]="+"
fi
IHTH

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

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

assign number value to alphabet in shell/bash

I have a script that prompts for the user to enter a 3 letter code. I need to convert that code to a number that corresponds to a=01, b=02....etc for the first two letters of that code.
For example the user enters ABC for $SITECODE I need to take the A&B and convert it to 0102 and store it to a new variable.
#!/bin/bash
# enable logging
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>/var/log/ULFirstBoot.log 2>&1
###################################### global variables ######################################################
# top level domain
tld="somedomain.com"
# grabs the serial number for ComputerName
serial=`/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/awk '/Serial\ Number\ \(system\)/ {print $NF}'`
# Cocoadialog location
CD="/Users/Shared/cocoaDialog.app/Contents/MacOS/cocoaDialog"
################################################### Begin Define Functions ####################################################
userinput () # Function will promt for Username,SItecode, and Region using Cocoadialog
{
# Prompt for username
rv=($($CD inputbox --title "User Name" --no-newline --informative-text "Please Enter the Users Employee ID" --icon "user" --button1 "NEXT" --button2 "Cancel"))
USERNAME=${rv[1]}
if [ "$rv" == "1" ]; then
echo "`date` User clicked Next"
echo "`date` Username set to ${USERNAME}"
elif [ "$rv" == "2" ]; then
echo "`date` User Canceled"
exit
fi
# Dialog to enter the User name and the create $SITECODE variable
rv=($($CD inputbox --title "SiteCode" --no-newline --informative-text "Enter Site Code" --icon "globe" --button1 "NEXT" --button2 "Cancel"))
SITECODE=${rv[1]} #truncate leading 1 from username input
if [ "$rv" == "1" ]; then
echo "`date` User clicked Next"
echo "`date` Sitecode set to ${SITECODE}"
elif [ "$rv" == "2" ]; then
echo "`date` User Canceled"
exit
fi
# Dialog to enter the Password and the create $REGION variable
rv=($($CD dropdown --title "REGION" --text "Choose Region" --no-newline --icon "globe" --items NA EULA AP --button1 "OK" --button2 "Cancel"))
item=${rv[1]}
if [[ "$rv" == "1" ]]
then echo "`date` User clicked OK"
elif [[ "$rv" == "2" ]]
then echo "`date` User Canceled"
exit
fi
if [ "$item" == "0" ]; then
REGION="NA"
echo "`date` Region set to NA"
elif [ "$item" == "1" ]; then
REGION="EULA"
echo "`date` Region set to EULA"
elif [ "$item" == "2" ]; then
REGION="AP"
echo "`date` Region Set to AP"
fi
# Confirm that settings are correct
rv=($($CD msgbox --text "Verify settings are correct" --no-newline --informative-text "USER-$USERNAME REGION-$REGION, SITE CODE-$SITECODE" --button1 "Yes" --button2 "Cancel"))
if [[ "$rv" == "1" ]]
then echo "`date` User clicked OK"
elif [[ "$rv" == "2" ]]
then echo "`date` User Canceled"
exit
fi
}
# Sets computername based
setname ()
{
ComputerName=$SITECODE$serial
/usr/sbin/scutil --set ComputerName $SITECODE$serial
echo "`date` Computer Name Set to" $(/usr/sbin/scutil --get ComputerName)
/usr/sbin/scutil --set LocalHostName $SITECODE$serial
echo "`date` LocalHostname set to" $(/usr/sbin/scutil --get LocalHostName)
/usr/sbin/scutil --set HostName $SITECODE$serial.$tld
echo "`date` Hostname set to" $(/usr/sbin/scutil --get HostName)
}
adbind ()
{
OU="ou=Computers,ou=${SITECODE}Win7,ou=$REGION,dc=global,dc=ul,dc=com"
echo "`date` OU will be set to $OU"
dsconfigad -add "global.ul.com" -username "user" -password "password" -ou "$OU"
dsconfigad -mobile "enable" -mobileconfirm "disable" -groups "Domain Admins, ADMIN.UL.LAPTOPADMINS"
}
# Checks if machine is succesfully bound to AD before proceeding
adcheck ()
{
until [ "${check4AD}" = "Active Directory" ]; do
check4AD=`/usr/bin/dscl localhost -list . | grep "Active Directory"`
sleep 5s
done
}
adduser () # creates mobile user account based on userinput function
{
# create mobile user account and home directory at /Users/username
/System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n $USERNAME -h /Users/$USERNAME
# Add newly created user to local admins group
dscl . -append /Groups/admin GroupMembership $USERNAME
# set login window to show username and password promts not a list of users
defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME 1
}
setADMPass ()
{
parsed1=${SITECODE:0:1}
parsed2=${SITECODE:1:1}
}
####################################### End define Functions ####################################################
############################################# Bgin Main Script #######################################################
userinput
setname
adbind
adcheck
adduser
echo $(dscl . -read /Groups/admin GroupMembership)
echo $(defaults 'read' /Library/Preferences/com.apple.loginwindow.plist SHOWFULLNAME)
# Reboot to apply changes
shutdown -r now "Rebooting to enable Mobile accounts"
Here's a funny way to do your encoding, abusing Bash's arithmetic:
string2code() {
# $1 is string to be converted
# return variable is string2code_ret
# $1 should consist of alphabetic ascii characters, otherwise return 1
# Each character is converted to its position in alphabet:
# a=01, b=02, ..., z=26
# case is ignored
local string=$1
[[ $string = +([[:ascii:]]) ]] || return 1
[[ $string = +([[:alpha:]]) ]] || return 1
string2code_ret=
while [[ $string ]]; do
printf -v string2code_ret '%s%02d' "$string2code_ret" "$((36#${string::1}-9))"
string=${string:1}
done
}
Try it:
$ string2code abc; echo "$string2code_ret"
010203
$ string2code ABC; echo "$string2code_ret"
010203
The magic happens here:
$((36#${string::1}-9))
The term 36# tells Bash that the following number is expressed in radix 36. In this case, Bash considers the characters 0, 1, ..., 9, a, b, c, ..., z (ignoring case). The term ${string:1} expands to the first character of string.
I found the answer thanks for all your help!
setADMPass ()
{
alower=abcdefghijklmnopqrstuvwxyz
site=$(echo $SITECODE | tr '[:upper:]' '[:lower:]')
parsed1=${site:0:1}
parsed2=${site:1:1}
tmp1=${alower%%$parsed1*} # Remove the search string and everything after it
ch1=$(( ${#tmp1} + 1 ))
tmp2=${alower%%$parsed2*} # Remove the search string and everything after it
ch2=$(( ${#tmp2} + 1 ))
if [[ $ch1 -lt 10 ]]; then
#statements
ch1=0$ch1
fi
if [[ $ch2 -lt 10 ]]; then
#statements
ch2=0$ch2
fi
passpre=$ch1$ch2
}
see if this helps! BASH 4+. If you find any issues, that'd be your homework.
#!/bin/bash
declare -A koba
i=1
for vi in {a..z};do koba=(["$vi"]="0${i}"); ((i++)); done
for vi in {A..Z};do koba=(["$vi"]="0${i}"); ((i++)); done
echo -en "\nEnter a word: "; read w; w="$( echo $w | sed "s/\(.\)/\1 /g" | cut -d' ' -f1,2)";
new_var="$(for ch in $w; do echo -n "${koba["${ch}"]}"; done)";
echo $new_var;

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