Bash陷阱,捕获并将它们作为相同函数的参数传递

时间:2016-12-16 15:54:58

标签: bash bash-trap

我正在开发一个管理一些陷阱的脚本。在开始时,我只使用此代码管理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

然后我尝试添加我想要管理的新陷阱,即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

然后,我决定在退出时根据陷阱做不同的事情,我不想为每个人创建不同的功能。我知道在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

有任何帮助吗?必须有一种方法来改善我的代码,只使用一个函数来处理所有陷阱,但我不知道如何......

1 个答案:

答案 0 :(得分:3)

您可以将参数传递给陷阱处理程序:

#!/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

在上面的代码中(在cygwin上测试,bash 4.3.46),capture_traps有一个参数:陷阱的名称。这是$1中的capture_traps。由于它一次只能获得一个陷阱,因此它不需要循环。

要设置陷阱,循环遍历您想要的每个陷阱(INT SIGTSTP ...)并运行

trap "capture_traps $f" "$f"

第一个参数可以比函数名更通用:它是

  

shell代码...每当shell收到信号或其他事件时都要读取和执行

wiki。因此,命令capture_traps $f(替换为陷阱名称)将在该特定陷阱上运行(第二个参数"$f"。等等!

...刚刚意识到我应该先检查重复项:)。 Here's another answerstill another