1

This works well:

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

But /tmp/.log.pipe is not removed when executed like this:

$source tailx.sh
$tailx error.log 10.21.xxx.xxx # /tmp/.log.pipe is not 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 "$@"
William Pursell
  • 204,365
  • 48
  • 270
  • 300
刘旭_
  • 56
  • 8
  • 2
    When does an `EXIT` trap fire? When you run your script by hand when does it exit? When you source your script into the current shell session when does it exit? – Etan Reisner Oct 03 '14 at 11:32

1 Answers1

0

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.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • Yes, thanks for your reply and you are right. I replace EXIT with INT, and the INT trap is fired when I press ctrl+c with sourcing the script. But, how to make the INT trap be fired with souring the script? – 刘旭_ Oct 03 '14 at 13:11
  • 1
    In a nutshell: `trap` and `source` don't mix. Try to replace the function with a shell script. That would a new subshell and `trap` would start to show a more useful behavior. – Aaron Digulla Oct 03 '14 at 14:17
  • Yeah, replace the function with a shell script could solve my problem. But, I have a bunch of functions which would auto be sourced in ~/.bashrc, also I want to source this function. I will add an alias in ~/.bashrc: $alias tailx='SCRIPT_HOME/tailx.sh'. – 刘旭_ Oct 03 '14 at 14:53
  • Why don't you put the script on the path? Try to put it into `$HOME/bin`, then you should be able to call it anywhere with just `tailx.sh`. If you want to call is as `tailx`, then rename it. – Aaron Digulla Oct 06 '14 at 07:19
  • 1
    bash also supports a trap on `RETURN` that executes when the function returns. Might be useful for the OP – William Pursell Mar 02 '17 at 05:26