#!/bin/sh -u # using SIGINT interrupt traps to change variables in running scripts # # $0 (no arguments) # # Demonstrate the use of interrupt traps to change a shell variable # value in a running script. # # NOTE: This script fragment is incomplete - it does not follow all # the script guidelines set out in "script_style.txt". It also # contains many "Instructor-Style" comments that you must not use in # your own scripts. See script_style.txt for details. # # -IAN! idallen@idallen.ca PATH=/bin:/usr/bin ; export PATH LC_COLLATE=C ; export LC_COLLATE LANG=C ; export LANG umask 022 # The Prompt function is called when the user sends a SIGINT interrupt. # SIGINT is usually caused by typing the CTRL-C character; but, you can # change it using the "stty" command, e.g. to ESC via: stty intr '^[' # Remember to reset the intr character before exit if you do change it! # # The interrupt trap is *disabled* when this function is running, # meaning that if you type another interrupt character, you will kill # your script. If you don't want that, you have to ignore interrupts # inside the interrupt function, as shown below. # # XXX All the input validation is missing here - normally you # XXX want to check for a valid numeric value and retry as needed. # XXX Don't set "x" until you know you have good, numeric input. # Prompt () { # Don't let a second interrupt kill the script - # ignore interrupts while reading user input. # trap '' 2 # disable SIGINT echo 1>&2 "Enter new input: " read x || exit # Restore the interrupt prompting function again and return to the # main script execution. # trap 'Prompt' 2 # enable SIGINT trap to Prompt function } # In the main program, consider carefully *where* you want to allow # your script to be interrupted, and only enable the trap around that # code. If you allow interrupts anywhere, the user might interrupt some # external command vital to the execution of the script; however, if # you only allow interrupts in some places, the user may signal SIGINT # at a place where interrupts are ignored. You have to trade off # responsiveness to SIGINT against possible corruption of script # functioning. If your script mostly does output and doesn't call # many external programs, you may wish to leave SIGINT always enabled. # # Allowing interrupts only around a sleeping part of a script is safest. # trap '' 2 # disable SIGINT let x=20 while [ $x -gt 0 ] ; do echo "x is $x" let x=x-1 trap 'Prompt' 2 # enable SIGINT trap to Prompt function sleep 1 # this sleep can be interrupted trap '' 2 # disable SIGINT done