Use the trap statement to catch signals and handle errors
You can define 'functions' in scripts using the following syntax:
die(){ echo "An error occurred." exit 2 }
You can simply call it as normal command:
die
You can pass arguments to function:
#!/bin/bash # define var file="/tmp/data.$$" # create function die(){ echo "$@" exit 2 } # ... call die if needed [ ! -f $file ] && die "$0: File $file not found." || echo "$0: File $file found."
The trap command and functions
You can use the trap command with shell functions as follows:
# define die()
die(){
echo "..."
}
# set trap and call die()
trap 'die' 1 2 3 15
....
...
The following is an updated shell script from how to clear a trap section:
#!/bin/bash # Shell script to find out odd or even number provided by the user # set variables to an integer attribute declare -i times=0 declare -i n=0 # define function warning(){ echo -e "\n*** CTRL+C and CTRL+Z keys are disabled. Please enter number only. Hit [Enter] key to continue..." } # capture CTRL+C, CTRL+Z and quit singles using the trap trap 'warning' SIGINT SIGQUIT SIGTSTP # set an infinite while loop # user need to enter -9999 to exit the loop while true do # get date read -p "Enter number (-9999 to exit) : " n # if it is -9999 die [ $n -eq -9999 ] && { echo "Bye!"; break; } # $n is 0, just get next number [ $n -eq 0 ] && continue # find out if $n is odd or evern ans=$(( n % 2 )) # display result [ $ans -eq 0 ] && echo "$n is an even number." || echo "$n is an odd number." # increase counter by 1 times=$(( ++times )) done # reset all traps trap - SIGINT SIGQUIT SIGTSTP # display counter echo "You played $times times." exit 0
The following example, add a user to the Linux system by updating /etc/passwd file and creating home directory at /home for user. It traps various single to avoid errors while creating user accounts. If user pressed CTRL+C or script terminated it will try to rollback changes made to system files. Traps are turned on before the useradd command in shell script, and then turn off the trap after the chpasswd line.
#!/bin/bash # setupaccounts.sh: A Shell script to add user to the Linux system. # set path to binary files ADD=/usr/sbin/useradd SETPASSWORD=/usr/sbin/chpasswd USERDEL=/usr/sbin/userdel # set variables HOMEBASE=/home HOMEDIR="" username="" # define function to clean up useradd procedure # handle errors using this function clean_up_useradd(){ # remove dir [ -d $HOMEDIR ] && /bin/rm -rf $HOMEDIR # remove user from passwd if exits grep -q "^${username}" /etc/passwd && $USERDEL ${username} # now exit exit } # make sure script is run by root else die [ $(id -u) -eq 0 ] || { echo "$0: Only root may add a user or group to the system."; exit 1;} # get username and password read -p "Enter user name : " username # create homedir path HOMEDIR="${HOMEBASE}/${username}" # capture 0 2 3 15 signals # if script failed while adding user make sure we clean up mess from # /home directory and /etc/passwd file # catch signals using clean_up_useradd() trap 'clean_up_useradd' SIGINT SIGQUIT SIGTERM # get password read -sp "Enter user password : " password # make sure user doesn't exits else die grep -q "^${username}" /etc/passwd && { echo "$0: The user '$username' already exits."; exit 2;} # create a home dir echo "Creating home directory for ${username} at ${HOMEDIR}..." [ ! -d ${HOMEDIR} ] && mkdir -p ${HOMEDIR} # Add user echo "Adding user ${username}..." ${ADD} -s /bin/bash -d ${HOMEDIR} ${username} || { echo "$0: User addition failed."; exit 3; } # Set a password echo "Setting up the password for ${username}..." #printf "%s|%s\n" $username $password | ${SETPASSWORD} || { echo "$0: Failed to set password for the user."; exit 3; } echo "$username:$password" | ${SETPASSWORD} || { echo "$0: Failed to set password for the user."; exit 3; } # reset all traps trap - 0 SIGINT SIGQUIT SIGTERM # add rest of the script...
You can run this script as follows: chmod +x setupaccounts.sh ./setupaccounts.sh Sample outputs:
Enter user name : testuser Enter user password : Creating home directory for testuser at /home/testuser... Adding user testuser... Setting up the password for testuser...