为什么这个简单的bash陷阱失败了

时间:2012-05-17 04:58:39

标签: bash bash-trap shell-trap

我仍然不熟悉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."

为什么我的陷阱功能没有被调用?

1 个答案:

答案 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 nonaptrap都不会返回任何输出。运行此脚本并获得“Naptime over”后。输出,trap返回trap -- 'nonap' SIGINTdeclare -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,它的工作正如我们所期望的那样:

.