Traps and Functions

The relationship between traps and shell functions is straightforward, but it has certain nuances that are worth discussing. The most important thing to understand is that functions are considered part of the shell that invokes them. This means that traps defined in the invoking shell will be recognized inside the function, and more importantly, any traps defined in the function will be recognized by the invoking shell once the function has been called. Consider this code:

settrap ( ) {
    trap "echo 'You hit control-C!'" INT
}
    
settrap
while true; do
    sleep 60
done

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

If you invoke this script and hit your interrupt key, it will print "You hit control-C!" In this case the trap defined in settrap still exists when the function exits.

Now consider:

loop ( ) {
    trap "echo 'How dare you!'" INT
    while true; do
        sleep 60
    done
}
    
trap "echo 'You hit control-C!'" INT
loop

When you run this script and hit your interrupt key, it will print "How dare you!" In this case the trap is defined in the calling script, but when the function is called the trap is redefined. The first definition is lost. A similar thing happens with:

loop ( ) {
    trap "echo 'How dare you!'" INT
}
    
trap "echo 'You hit control-C!'" INT
loop
while true; do
    sleep 60
done

Once again, the trap is redefined in the function; this is the definition used once the loop is entered.

We'll now show a more practical example of traps.


Task 8-2

As part of an electronic mail system, write the shell code that lets a user compose a message.


The basic idea is to use cat to create the message in a temporary file and then hand the file's name off to a program that actually sends the message to its destination. The code to create the file is very simple:

msgfile=/tmp/msg$$
cat > $msgfile

Since cat without an argument reads from the standard input, this will just wait for the user to type a message and end it with the end-of-text character CTRL-D.