结束时间戳不打印在 Shell 脚本上:使用 trap
我有一个用于部署的 shell 脚本。由于我想捕获整个过程的输出,因此我将其包装在一个子 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"
#
########################################################################
在使用该子 shell 之前,trap
命令起作用了。当您按下 CNTL-C
时,程序将打印 Stopping Script:
和日期。
但是,我想确保没有人忘记保存该脚本的输出,因此我使用子 shell 来自动保存输出。而且,现在 trap
似乎不起作用。
我做错了什么?
新信息
多玩一点。我现在发现问题不在于 shell 或子 shell。这就是该死的管子!
如果我不将输出通过管道传输到tee,则陷阱可以正常工作。如果我将输出通过管道传输到 tee
,则 trap
不起作用。
因此,真正的问题是如何tee输出并且仍然能够使用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....
。最下面那张没有。最下面的一个,陷阱起作用了。最上面的一个,陷阱没有。看看是否可以让管道工作,并将“脚本被杀死”行打印到 tee out 文件中。
管道确实有效。陷阱没有,但只有当我有管子时。您可以将 trap
语句四处移动,并放入一层又一层的子 shell。我做的一些小事是错误的,我不知道那是什么。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于 trap 停止了正在运行的进程 – logShell.sh – 我认为管道根本没有被执行。你不能这样做。
一种解决方案可能是编辑 logShell.sh 以在日志文件中逐行写入。也许您可以将其发布,我们可以讨论您如何管理它。
好的,现在我明白了。您必须使用 tee 和 -i 来忽略中断信号。
这个效果很好!
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.
this one works fine!