bash中的陷阱语法问题

bash中的陷阱语法问题,bash,shell,syntax,bash-trap,shell-trap,Bash,Shell,Syntax,Bash Trap,Shell Trap,我打算使用trap在出现故障时执行一些清理代码。我有下面的代码,但似乎有一些语法问题 #!/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 是否有人认为陷阱的编写方式存在问题。

我打算使用trap在出现故障时执行一些清理代码。我有下面的代码,但似乎有一些语法问题

#!/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\u DEV1和$LOOP\u DEV2从主脚本发送到陷阱,然后发送到handle\u error函数,会怎么样?现在,它们在主脚本中作为环境变量导出。我搜索了一些陷阱示例,但找不到类似的例子

编辑


我将shebang从/bin/sh更改为/bin/bash。由于/bin/sh已经被符号链接到bash,我没有想到会有独角兽,也没有看到任何独角兽。

这个trap调用正在创建一个有趣的递归,因为
$bash_COMMAND
(和
$?
)在执行
trap
命令时正在展开。但是,此时的
$BASH_命令
是trap命令本身,文本上包括
$BASH_命令
(以及一些引号和分号)。实际上,找出陷阱触发时要执行的命令是一项有趣的研究,但没有必要解决问题,您可以这样做:

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

请注意,将
替换为
不仅可以避免立即的参数扩展,还可以避免必须转义内部的
s.

如果脚本实际上是用
sh而不是
bash
执行的,则需要用
handle\u error(){
函数
关键字是一个
bash
扩展。@chepner在大多数情况下不是/bin/sh到bash的符号链接吗?至少在我的系统中似乎是这样。如果使用bash语法,那么应该在shbang行中指定
#!/bin/bash
,即使
/bin/sh
是到
/b的符号链接在/bash
中。这样,如果您的脚本在系统上运行时,
/bin/sh
不是
/bin/bash
的符号链接,它仍然可以正常工作。此外,如果
bash
/bin/sh
的名称运行,则可能会禁用某些功能,尽管这里的情况似乎不是这样。看起来正在工作。非常感谢.Will post,如果我找出了作为递归结果尝试执行的命令。@braindead:您可以通过键入
trap
并查看与ERR关联的命令来作弊,尽管您必须仔细查看引号。您会看到它两次调用handle\u error,但在两次调用之间,它会尝试执行xecute
“}ERR失败,状态代码为0”
,这会导致您看到错误消息。请记住,
{
}
不是自定界字符;我移动了上面的
,以使发生的事情更加明显,尽管
是在
之前还是之后没有区别