2013-07-13 41 views
1

我打算在发生故障时使用陷阱执行一些清理代码。我有以下代码,但它似乎有一些语法问题。bash中的陷阱语法问题

#!/bin/bash 

set -e 

function handle_error { 
    umount /mnt/chroot 
    losetup -d $LOOP_DEV1 $LOOP_DEV2 
} 

trap "{ echo \"$BASH_COMMAND failed with status code $?\"; handle_error; }" ERR 

是否有人看到陷阱写入方式的问题。如果发生错误,陷阱会被正确执行,但它也会在下面引发另一个不需要的错误消息。

/root/myscript.sh: line 60: } ERR with status code 0: command not found 
##line 60 is that line of code that exited with a non zero status 

如何正确写入以避免错误信息?另外,如果我必须将参数$ LOOP_DEV1和$ LOOP_DEV2从主脚本发送到陷阱,然后发送到handle_error函数呢?现在它们被作为主脚本中的环境变量导出。我做了一些搜索陷阱的例子,但我无法得到类似的东西。

编辑

我从/ bin/sh的为/ bin/bash的改变的家当。由于/ bin/sh已经符合bash的标准,我没有想到独角兽也没有看到任何东西。

+0

如果脚本实际上是用'sh'而不是'bash'执行的,则需要用'handle_error(){'定义函数。 'function'关键字是一个'bash'扩展名。 – chepner

+0

@chepner在大多数情况下,不是/ bin/sh连接到bash的sym链接?至少在我的系统中似乎是这种情况。 –

+2

如果你使用Bash语法,那么你应该在shbang行中指定'#!/ bin/bash',即使'/ bin/sh'是'/ bin/bash'的符号链接。那样的话,如果你的脚本曾经在'/ bin/sh'不是'/ bin/bash'的系统上运行,它仍然可以正常工作。 –

回答

2

该陷阱调用正在创建一个有趣的递归,因为$BASH_COMMAND(和$?)在执行trap命令时正在展开。但是,$BASH_COMMAND在这一点上是陷阱命令本身,文本上包括$BASH_COMMAND(以及一些引号和分号)。其实搞清楚什么时候陷阱火灾是一项有趣的研究要执行的命令,但它不是必要措施来解决这个问题,你可以这样做:

trap '{ echo "$BASH_COMMAND failed with status code $?"; handle_error; }' ERR 

注意更换"'不仅避免立即进行参数扩展,这也避免了必须逃离内部" s。

+0

似乎正在工作。非常感谢。如果我找出试图作为递归结果执行的命令,将会发布。 –

+0

@braindead:只要输入'trap'并查看与ERR关联的命令是什么,就可以作弊,尽管您必须仔细查看引号。你会看到它调用了两次handle_error,但是在两次调用之间,它试图执行'“} ERR失败,状态码为0”',这导致你看到的错误信息。请记住'{'和'}'不是自定义字符;我移动了上面的'''使它更加明显,但'''在'}'之前还是之后没有区别。 – rici