如何在Bash脚本退出之前运行命令?

Dav*_*ver 111 bash

如果Bash脚本有set -e,并且脚本中的命令返回错误,如何在脚本退出之前进行一些清理?

例如:

#!/bin/bash
set -e
mkdir /tmp/foo
# ... do stuff ...
rm -r /tmp/foo
Run Code Online (Sandbox Code Playgroud)

/tmp/foo即使其中一个命令... do stuff ...失败,我怎样才能确保删除它?

dev*_*vid 179

以下是使用陷阱的示例:

#!/bin/bash -e

function cleanup {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}

trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails
Run Code Online (Sandbox Code Playgroud)

输出:

dbrown@luxury:~ $ sh traptest
t: line 9: asdffdsa: command not found
Removing /tmp/foo
dbrown@luxury:~ $
Run Code Online (Sandbox Code Playgroud)

请注意,即使asdffdsa行失败,仍会执行清理.

  • 可能涉及的对象:当有人使用 Ctrl+D 或“exit”结束当前 bash 会话时,也会执行此操作。 (3认同)

dmc*_*kee 10

bash联机帮助页(关于内置函数):

trap [-lp] [[arg] sigspec ...]
当shell收到信号sigspec时,将读取并执行命令arg.

因此,正如Anon.的回答所示,trap在脚本中尽早调用以设置ERR所需的处理程序.

  • 你也可以在EXIT上陷阱. (3认同)
  • 运行“help trap”来查看内置的一些帮助。 (2认同)

Ano*_*on. 7

来自参考set:

-e

如果一个简单的命令(参见3.2.1简单命令)以非零状态退出,则立即退出,除非失败的命令是until或while循环的一部分,if语句的一部分,&&或||的一部分.列表,或者如果使用!反转命令的返回状态.ERR上的陷阱(如果已设置)将在shell退出之前执行.

(强调我的).

  • 使用“-e”时可能值得添加“-E”,请参阅https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/ (2认同)

Saf*_*ver 6

shdevguydavid 的回答版本。

#!/bin/sh
set -e
cleanup() {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}
trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails
Run Code Online (Sandbox Code Playgroud)

参考:shellscript.sh