【发布时间】:2010-01-25 02:42:15
【问题描述】:
如果 Bash 脚本有set -e,并且脚本中的命令返回错误,我该如何在脚本退出之前进行一些清理?
例如:
#!/bin/bash
set -e
mkdir /tmp/foo
# ... do stuff ...
rm -r /tmp/foo
即使... do stuff ... 中的命令之一失败,我如何确保删除/tmp/foo?
【问题讨论】:
标签: bash
如果 Bash 脚本有set -e,并且脚本中的命令返回错误,我该如何在脚本退出之前进行一些清理?
例如:
#!/bin/bash
set -e
mkdir /tmp/foo
# ... do stuff ...
rm -r /tmp/foo
即使... do stuff ... 中的命令之一失败,我如何确保删除/tmp/foo?
【问题讨论】:
标签: bash
这里是一个使用陷阱的例子:
#!/bin/bash -e
function cleanup {
echo "Removing /tmp/foo"
rm -r /tmp/foo
}
trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails
输出:
dbrown@luxury:~ $ sh traptest
t: line 9: asdffdsa: command not found
Removing /tmp/foo
dbrown@luxury:~ $
请注意,即使 asdffdsa 行失败,清理仍会执行。
【讨论】:
来自bash 联机帮助页(关于内置):
陷阱 [-lp] [[arg] sigspec ...]
命令 arg 将在 shell 时被读取并执行 接收信号 sigspec。
因此,如 Anon.'s answer 中所述,请在脚本的早期调用 trap 以在 ERR 上设置所需的处理程序。
【讨论】:
help trap 以查看有关内置的一些帮助。
sh devguydavid 的answer 的版本。
#!/bin/sh
set -e
cleanup() {
echo "Removing /tmp/foo"
rm -r /tmp/foo
}
trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails
【讨论】:
POSIX 让我微笑。 :) 您也链接到了很棒的教学网站。
来自set的参考:
-e
如果简单命令(参见第 3.2.1 节简单命令)以非零状态退出,则立即退出,除非失败的命令是 until 或 while 循环的一部分、if 语句的一部分、&& 的一部分或 ||列表,或者如果命令的返回状态正在使用 ! 反转。 如果设置了 ERR 陷阱,则会在 shell 退出之前执行。
(强调我的)。
【讨论】:
我不知道是之前还是之后对你来说是否重要。
您可以设置脚本在使用“trap”关闭后立即运行。然后你就可以关闭终端了。
例如;
trap ./val.sh EXIT #set command you want to run after close terminal
kill -9 $PPID #kill current terminal
【讨论】: