2012-05-17 63 views
3

我对bash脚本还很陌生,而且我很难弄清楚为什么这个简单的陷阱没有按预期工作。为什么这个简单的bash陷阱失败

目标 - 创建可选等待期间,可以通过按CTRL + Ç被跳过。

紧迫的预期结果CTRL +Ç - 立即呼应 “!没时间午睡”并退出。按压的

实际结果CTRL + Ç - 立即回声 “小睡之上”并退出。

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

这工作对我很好。你的环境是什么? – Adam

+1

我只是(在bash 3.2.25古老的Linux)尝试过了,在'trap.sh'保存你的代码,跑'庆典trap.sh',并得到了:'睡5秒,按Ctrl-C现在继续当我按照你的意料打断时,接着是“没时间打盹!”。 –

+0

感谢您的反馈。至少我知道它*应该*按预期工作。我使用最新版本的Tinycore Linux和GNU bash,版本为4.0.33(1)的版本(i686-pc-linux-gnu)。在打开一个新终端时,声明-f nonap和trap都不返回任何输出。运行此脚本并获得“午睡”。输出,'trap'返回'陷阱 - “非AP” SIGINT'和'声明-f在我的脚本中定义nonap'返回的功能。 –

回答

4

我只是(在bash 3.2.25在一个古老的RHEL Linux)的试了一下,在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)的版本(i686-pc-linux-gnu)。在打开新的终端时,declare -f nonaptrap都不返回任何输出。运行此脚本并获得“午睡”。输出,trap返回trap -- 'nonap' SIGINTdeclare -f nonap返回我的脚本中定义的函数。

对此我的回答:

你是如何运行此脚本,然后呢?使用source.来读取它?是啊;你一定是。我只是试过了,而采购中断给了我Naptime over.;输入另一个中断虽然给我No time for napping!和壳退出。它第二次表现得如预期一样;点击脚本时我不确定中断是怎么回事。这是意想不到的行为。

你为什么要来源或点这?为什么不把它用作简单的旧脚本?

没有理由来源...我只是用它来测试时运行它。我想我在使用时从来没有遇到像这样的任何异常情况。之前,但我仍然是一个新手。我看到了相同的结果,如果我使用bash运行它,它在第一次中断时会按预期工作。

嗯,有一个“医生,医生,它伤害时,我打我的头撞墙”组件以下建议,但也有基本的实用主义也有。

您使用source(在C shell或bash)或.(在伯恩,科恩,POSIX壳或bash)有脚本影响调用shell的环境,而不是运行作为一个子shell。解决问题(尽管主要是通过侥幸)的赠品是当你在运行脚本后报告,你已经定义了该功能;除非您使用source,否则不会发生这种情况。在这种情况下,很显然你不想在调用shell中设置trap。当我(与提示Toru JL:ksh)跑了,我得到了:

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,则需要将trap INT添加到脚本的末尾,并且您可能还想取消定义该功能。

但是,我认为,将它隔离在一个shell中并将其作为一个子进程运行它会更好。

但是......当脚本来源时,你发现这种事情玩弄有趣的游戏很有趣。这是bash行为中的一个小异常。我不确定它会上升到'错误'的水平;我必须仔细阅读大量的手册(可能多次),并在声明“错误”之前咨询其他知识渊博的人员。

我不知道这将是任何安慰,但我想ksh你的脚本.和它的工作,因为我们俩都期待:

Toru JL: ksh 
$ . trap.sh 
Sleeping for 5 seconds, hit ctrl-c to proceed now. 
No time for napping! 
Toru JL: 
+0

再次感谢您的深思。我正在审查源/。在你发现那是造成问题之后。从我能收集的信息来看,听起来就像你死了一样。我不相信这是一个“错误”,也许只是一个细微的理由,我没有完全掌握。 –

+0

除非我有充分理由这样做,否则我将从现在开始运行所有脚本。所以,你解决了我眼前的问题,并教给我一个关于在这个过程中调用脚本的好教训。再次感谢! –

+0

+1 - Zsh的行为与ksh相同。 –