1

我有一个用于部署的 shell 脚本。因为我想捕获整个过程的输出,所以我将它包装在一个子外壳中并将其拖尾:

#! /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"
#
########################################################################

在我使用 subshel​​l 之前,该trap命令有效。当您按下CNTL-C时,程序将打印Stopping Script:日期和日期。

但是,我想确保没有人忘记保存这个脚本的输出,所以我使用了 subshel​​l 来自动保存输出。而且,现在trap似乎不起作用。

我究竟做错了什么?


新的信息

多玩一点。我现在看到问题不在于外壳或子外壳。这该死的管子!

如果我不将输出通过管道传输到tee,则trap工作正常。如果我将输出通过管道传输到tee,则trap不起作用。

所以,真正的问题是我如何打开输出并且仍然能够使用trap


测试程序

在您回答之前,请尝试以下测试程序:

#! /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

#! /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
)

顶部的管道连接到somefile..... 最下面的没有。最下面的,陷阱有效。最重要的是,陷阱没有。看看你是否可以让管道工作并且“脚本被杀死”行打印到 teed out 文件中。

管道确实有效。陷阱没有,但只有当我有管道时。您可以将trap语句四处移动并放入一层又一层的子壳。我做的一些小事情是错误的,我不知道它是什么。

4

1 回答 1

1

由于陷阱停止了正在运行的进程——logShell.sh——我认为管道根本没有被执行。你不能这样做。

一种解决方案可能是编辑 logShell.sh 以在日志文件中逐行写入。也许您可以发布它,我们可以讨论您如何管理它。

好的,现在我明白了。您必须使用 tee 和 -i 来忽略中断信号。

#! /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

这个很好用!

于 2011-04-08T11:10:03.093 回答