Trapping signals in scripts.

trap command allows user to trap many signals. trap 'cmd-sequence' sig-id [sig-id] User may specify a number of actions to take when a signal is trapped. User may specify different traps (actions) for different signals. User may specify a number of signals for a particular trap. User may redefine a trap in different places in a script. Trap traps most signals and can ignore signal completely. or modify the default action normally taken for a given signal. If defined in a function, a trap may either terminate script or return from function continue execution of the function after taking some action, or continue execution of the function after doing nothing. SIGKILL and SIGSTOP are untrappable.
  • trap - keyword.
  • 'command sequence' - sequence of actions.
  • sig-id - list of signal numbers that are trapped by this trap. Not all signals can be trapped. # [ctrl]c, INT trap 'echo "You should use q"; exit 2' 2 # Standard termination, kill -15 trap 'echo "Your sum is $sum"' EXIT # HUP - ignore trap '' 1
    #!/bin/bash
    # trap [ctrl] c and trash talk user before quitting. 
    trap "echo ' Hah!, Giving up!'; exit 1" 2
    
    # Get a random number from 0-99
    target=$( expr $RANDOM % 100 )
    
    # get first guess
    read -p "guess : " guess
    until echo "$guess" | grep "^[0-9][0-9]*$" > /dev/null 2>&1
    do
      read -p "guess : " guess
    done
    
    # set guess count to 1
    # test guess against target
    #  if mis-guess then test for too high or low
    # increment guess count if missed.
    for (( i = 1; "$guess" != "$target"; i++ ))
    do
      if [ "$guess" -gt "$target" ]
      then
         echo "too high"
      else
         echo "too low"
      fi
    
      read -p "guess : " guess
      until echo "$guess" | grep "^[0-9][0-9]*$" > /dev/null 2>&1
      do
        read -p "guess : " guess
      done
    
    done
    
    # show target and number of guesses.
    echo "$target in $i guesses"
    

    
    #!/bin/bash
    
    #initialize some variables 
    ans=0  # variable for digit being inputted.
    sum=0  # sum of digits inputted.
    urc=0   # storage for return code.
    
    ask ()
    {
      #ask prompt user for a single digit other than 0.
      #  while user gives an invalid input, 
      #    keep re-asking.
      # If user issues a ctrl-c, 
      #   then trap and return from ask with a code of 23
      # 
      # valid digit will be stored in ans which is accessible 
      #   in main code block.
    
      # trap ctrl-c - INTR 
      # if ctrl-c entered while in this loop
      #   set return code of ask function to 23 and return.
      #
      #   because 'while' tests actual return code of ask
      #     user needs to preserve a return code for later.    
      trap "urc=23; return 1;" 2
    
      # grep test the string in $ans for NOT (-v) a single non-zero digit.
      # while this is true 
      while echo "$ans" | grep -v "^[1-9q]$" >/dev/null 2>&1
      do
        # prompt user for a single digit.  
        echo -c "Input 1 digit 1-9 : "
        # read input from user.
        read ans
      done  
    }
    
    
    # invoke the ask to get a digit.
    # ask won't return unless a valid digit or ctrl-c is issued.
    while ask
    do
      # check for user return code 23 (ctrl-c used)
      if [ "$urc" -eq 23 ]
      then
        # tell user and reset return code.
        echo "interrupt detected"
        # reset urc for next call of ask
        urc=0
    
        # go back to top of loop and ask again.
        continue
      
      fi
      
      # process digit provided.
      echo "you picked $ans"
    
      # if user specified q - for quit. Then break out of ask loop.
      if [ $ans = "q" ]
      then 
        break
      fi
    
      sum=`expr $sum + $ans`
    
      # check to see if sum is maxed (over 100)
      if [ $sum -gt 100 ]
      then
        # if so, quit ask loop.
        break
      else
        ans=0
      fi
    done
    
    # show final total.
    echo "sum = $sum"