Ending Timestamp not printing on Shell Script: Using trap

1.4k Views Asked by At

I have a shell script I use for deployments. Since I want to capture the output of the entire process, I've wrapped it in a subshell and tail that out:

#! /usr/bin/env ksh
# deploy.sh
########################################################################

(yadda, yadda, yadda)

########################################################################
# LOGGING WRAPPER
#
dateFormat=$(date +"%Y.%m.%d-%H.%M.%S")
(
print -n "EXECUING: $0 $*: "
date
#
########################################################################

(yadda, yadda, yadda)

#
# Tail Startup
#

trap 'printf "Stopping Script: ";date;exit 0"' INT
print "TAILING LOG: YOU MAY STOP THIS WITH A CTRL-C WHEN YOU SEE THAT SERVER HAS STARTED"
sleep 2
./tailLog.sh
) 2>&1 | tee "deployment.$dateFormat.log"
#
########################################################################

Before I employed the subshell, the trap command worked. When you pressed CNTL-C, the program would print Stopping Script: and the date.

However, I wanted to make sure that no one forgets to save the output of this script, so I employed the subshell to automatically save the output. And, now trap doesn't seem to be working.

What am I doing wrong?


NEW INFORMATION

A little more playing around. I now see the issue isn't the shell or subshell. It's the damn pipe!

If I don't pipe the output to tee, the trap works fine. If I pipe the output to tee, the trap doesn't work.

So, the real question is how do I tee the output and still be able to use trap?


TEST PROGRAM

Before you answer, please, please, try these test programs:

#! /bin/ksh

dateFormat=$(date +"%Y.%m.%d-%H:%M:%S")
(
trap 'printf "The script was killed at: %s\n", "$(date)"' SIGINT
echo "$0 $*"
while sleep 2
do
    print -n "The time is now "
    date
done
)  | tee somefile

And

#! /bin/ksh

dateFormat=$(date +"%Y.%m.%d-%H:%M:%S")
(
trap 'printf "The script was killed at: %s\n", "$(date)"' SIGINT
echo "$0 $*"
while sleep 2
do
    print -n "The time is now "
    date
done
)

The top one pipes to somefile..... The bottom one doesn't. The bottom one, the trap works. The top one, the trap doesn't. See if you can get the pipe to work and the "The script was killed at" line to print into the teed out file.

The pipe does work. The trap doesn't, but only when I have the pipe. You can move the trap statement all around and put in layers and layers of sub shells. There's some minor thing I am doing that's wrong, and I have no idea what it is.

1

There are 1 best solutions below

3
On BEST ANSWER

Since trap stops the running process – logShell.sh – I think the pipe doesn't get executed at all. You can't do it this way.

One solution could be editing logShell.sh to write line by line in your log file. Maybe you could post it and we can discuss how you manage it.

OK, now I've got it. You have to use tee with -i to ignore interrupt signals.

#! /bin/ksh

dateFormat=$(date +"%Y.%m.%d-%H:%M:%S")
(
trap 'printf "The script was killed at: %s\n", "$(date)"' SIGINT
echo "$0 $*"
while sleep 2
do
    print -n "The time is now "
    date
done
)  | tee -i somefile

this one works fine!