刘旭_ 刘旭_ -4 years ago 102
Bash Question

Why trap signals do not work in Shell functions?

This works well:

$./tailx.sh error.log 10.21.xxx.xxx # Works


But /tmp/.log.pipe cannot be removed like this:

$source tailx.sh
$tailx error.log 10.21.xxx.xxx # /tmp/.log.pipe cannot be removed


I want to know why and how?

Here is my code. I use it to tail logs on remote machines.

#!/bin/bash
# tailx error.log hostname
function tailx {

[ $# -lt 2 ] && echo "Invalid input" && return
# do clean,
local LOG_PIPE=/tmp/.log.pipe
local LOG_FILE=$1
trap 'echo Exting..... >&2 && [ -e $LOG_PIPE ] && rm $LOG_PIPE ' EXIT
# fix path
[ / != ${LOG_FILE:0:1} ] && LOG_FILE=`pwd`"/"$LOG_FILE

[ -e $LOG_PIPE ] || mkfifo $LOG_PIPE

# iterate host, tail log
shift
until [ $# -eq 0 ]
do
ssh $1 "tail -f $LOG_FILE | awk 'BEGIN{\"hostname\"|getline HOST; } {print HOST, \$0}'" > $LOG_PIPE &
shift
done

cat $LOG_PIPE

}

tailx "$@"

Answer Source

The EXIT trap is fired when the shell terminates. It's easier to understand when you look at ./tailx.sh. The running shell expands that into $SHELL $PWD/tailx.sh .... That means a new shell process is created (a.k.a. a subshell).

EXIT fires when this child process terminates.

If you source the script, the trap gets attached to the current shell, so it will be executed when you close the terminal window or you log out.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download