我仍然不熟悉bash脚本,而且我很难弄清楚为什么这个简单的陷阱没有按预期工作。
目标 - 按 CTRL + C 创建可跳过的可选等待期。
按 CTRL + C 的预期结果 - 立即回复“没时间打盹!”并退出。
按 CTRL + C 的实际结果 - 立即回显“naptime over”。并退出。
#!/bin/bash
nonap() {
echo "No time for napping!"
exit
}
trap nonap INT
echo "Sleeping for 5 seconds, hit ctrl-c to proceed now."
sleep 5
echo "Naptime over."
为什么我的陷阱功能没有被调用?
答案 0 :(得分:4)
我刚尝试过(在一个古老的RHEL Linux上使用bash 3.2.25)并将代码保存在trap.sh
中,运行bash trap.sh
,然后得到:
Sleeping for 5 seconds, hit ctrl-c to proceed now.
接下来是:
No time for napping!
当我中断时,正如你所期待的那样。当我让它在没有中断的情况下运行时,我收到了预期的消息:
Naptime over.
然后您评论道:
至少我知道应按预期工作。我正在使用最新版本的Tinycore Linux和GNU bash,版本4.0.33(1)-release(i686-pc-linux-gnu)。打开新终端后,
declare -f nonap
和trap
都不会返回任何输出。运行此脚本并获得“Naptime over”后。输出,trap
返回trap -- 'nonap' SIGINT
,declare -f nonap
返回我脚本中定义的函数。
我回复了:
那么你是如何运行这个脚本的呢?使用source
或.
来阅读它?没错;你一定是。我刚尝试过,而采购中断给了我Naptime over.
;键入另一个中断虽然给了我No time for napping!
并退出了shell。第二次表现如预期;在点击脚本时我不确定中断是什么。这是意想不到的行为。
你为什么要采购或点这个?为什么不把它用作一个普通的旧脚本呢?
没有理由采购......我只是在测试时使用它来运行它。我想我在使用时从未遇到任何类似的异常现象。以前,但我也是新手。我看到了相同的结果,如果我用bash运行它,它会在第一个中断时按预期工作。
嗯,有一个“博士,医生,当我把头撞到墙上时会受到伤害”组成部分提到以下建议,但那里也有基本的实用主义。
您使用source
(在C shell或bash
中)或.
(在Bourne,Korn,POSIX shell或bash
中)让脚本影响环境调用shell,而不是作为子shell运行。解决问题的方法(尽管主要是侥幸)是当你报告在运行脚本后,你已经定义了函数;除非您使用source
,否则不会发生这种情况。在这种情况下,很明显您不希望在调用shell中设置trap
。当我运行它时(来自带有提示ksh
的{{1}}),我得到了:
Toru JL:
'没时间打盹!'当我再次按下中断键时出现消息,它终止了Toru JL: bash
bash-3.2$ trap
bash-3.2$ source trap.sh
Sleeping for 5 seconds, hit ctrl-c to proceed now.
Naptime over.
bash-3.2$ trap
trap -- 'nonap' INT
bash-3.2$ No time for napping!
Toru JL:
我跑了。如果您继续将其与bash
一起使用,则需要将source
添加到脚本的末尾,并且您可能还想取消定义该函数。
但是,我认为最好将它全部隔离在shell中并将其作为子进程运行。
但是......你发现这种东西在脚本来源时玩有趣的游戏很有趣。 trap INT
的行为是一个小小的异常现象。我不确定它会上升到'bug'的水平;我必须仔细阅读大量手册(可能是几次),并在声称'bug'之前咨询其他知识渊博的人。
我不确定这会有什么安慰,但我在bash
的脚本上尝试了ksh
,它的工作正如我们所期望的那样:
.