结束时间戳不打印在 Shell 脚本上:使用 trap

发布于 2024-10-29 07:25:35 字数 1967 浏览 6 评论 0原文

我有一个用于部署的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

本宫微胖 2024-11-05 07:25:35

由于 trap 停止了正在运行的进程 – 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

这个效果很好!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文