2014-10-03 86 views
0

这非常适用:为什么陷阱信号在Shell函数中不起作用?

$./tailx.sh error.log 10.21.xxx.xxx # /tmp/.log.pipe is removed 

但是,当这样执行/tmp/.log.pipe不会被删除:

$source tailx.sh 
$tailx error.log 10.21.xxx.xxx # /tmp/.log.pipe is not removed 

我想知道为什么和怎么样?

这是我的代码。我用它来远程机器上的日志。

#!/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 "[email protected]" 
+2

什么时候“EXIT”陷阱触发?手动运行脚本时何时退出?当您将脚本编入当前shell会话时何时退出? – 2014-10-03 11:32:44

回答

0

EXIT陷阱在shell终止时触发。当你看到./tailx.sh时,它更容易理解。运行中的shell将其扩展为$SHELL $PWD/tailx.sh ...。这意味着创建一个新的shell进程(a.k.a. subshel​​l)。

EXIT此子进程终止时触发。

如果您使用source脚本,该陷阱会附加到当前shell,因此它将在您关闭终端窗口或注销时执行。

+0

是的,谢谢你的回复,你是对的。我用INT替换EXIT,并且当我按脚本ctrl + c来触发INT陷阱。但是,如何让INT陷阱被炒作剧本? – 2014-10-03 13:11:39

+1

简而言之:'trap'和'source'不会混合。尝试用shell脚本替换该函数。这将是一个新的子shell和'陷阱'将开始显示更有用的行为。 – 2014-10-03 14:17:13

+0

是的,用shell脚本替换函数可以解决我的问题。但是,我有一堆可以在〜/ .bashrc中自动获取的函数,我也希望获得这个函数。我将在〜/ .bashrc中添加一个别名:$ alias tailx ='SCRIPT_HOME/tailx.sh'。 – 2014-10-03 14:53:50