我正在开发一个管理一些陷阱的脚本。一开始我只用这段代码管理 INT 和 SIGTSTP,它运行得很好:
#!/bin/bash
function capture_traps() {
echo -e "\nDoing something on exit"
exit 1
}
trap capture_traps INT
trap capture_traps SIGTSTP
read -p "Script do its stuff here and we use read for the example we pause for time to generate trap event"
exit 0
Run Code Online (Sandbox Code Playgroud)
然后我尝试添加我想要管理的新陷阱,即 SIGINT 和 SIGHUP。首先,我这样做了(这是有效的):
#!/bin/bash
function capture_traps() {
echo -e "\nDoing something on exit"
exit 1
}
trap capture_traps INT
trap capture_traps SIGTSTP
trap capture_traps SIGINT
trap capture_traps SIGHUP
read -p "Script do its stuff here and we use read for the example we pause for time to generate trap event"
exit 0
Run Code Online (Sandbox Code Playgroud)
然后,我决定根据陷阱在退出时执行不同的操作,并且我不想为每个陷阱创建不同的函数。我知道在 bash 中你可以使用命名法循环遍历函数上的参数for item in $@; do,所以我尝试了,但试图区分陷阱的类型似乎不起作用。我编写了这段代码,但它不起作用。
#!/bin/bash
function capture_traps() {
for item in $@; do
case ${item} in
INT|SIGTSTP)
echo -e "\nDoing something on exit"
;;
SIGINT|SIGHUP)
echo -e "\nDoing another thing even more awesome"
;;
esac
done
exit 1
}
trap capture_traps INT SIGTSTP SIGINT SIGHUP
read -p "Script do its stuff here and we use read for the example we pause for time to generate trap event"
exit 0
Run Code Online (Sandbox Code Playgroud)
有什么帮助吗?必须有一种方法可以改进我的代码,仅使用一个函数来处理所有陷阱,但我不知道如何......
您可以将参数传递给陷阱处理程序:
#!/bin/bash
function capture_traps() {
#for item in $@; do
case "$1" in
INT|SIGTSTP)
echo -e "\nDoing something on exit"
;;
SIGINT|SIGHUP)
echo -e "\nDoing another thing even more awesome"
;;
esac
#done
exit 1
}
for f in INT SIGTSTP SIGINT SIGHUP ; do
trap "capture_traps $f" "$f"
done
read -p "Script do its stuff here and we use read for the example we pause for time to generate trap event"
exit 0
Run Code Online (Sandbox Code Playgroud)
在上面的代码中(在 cygwin、bash 4.3.46 上测试),capture_traps采用一个参数:陷阱的名称。那是$1在capture_traps. 由于它一次只获取一个陷阱,因此不需要循环。
要设置陷阱,循环会迭代您想要的每个陷阱 ( INT SIGTSTP...) 并运行
trap "capture_traps $f" "$f"
Run Code Online (Sandbox Code Playgroud)
第一个参数可以比函数名更通用:它是
shell 代码...每当 shell 接收到信号或另一个事件时就会被读取和执行
根据维基百科。因此,该命令capture_traps $f(用陷阱名称替换)将在该特定陷阱(第二个参数,"$f".Et voila!
...刚刚意识到我应该先检查重复项:)。 这是另一个答案,还有另一个答案。