Баш ловит, захватывает и передает их в качестве аргументов для той же функции

Я разрабатываю скрипт, который управляет некоторыми ловушками. В начале я управлял только 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 ответ

Решение

Вы можете передать аргументы вашему обработчику ловушек:

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

Первый аргумент может быть более общим, чем имя функции: это

код оболочки... для чтения и выполнения всякий раз, когда оболочка получает сигнал или другое событие

по вики. Поэтому команда capture_traps $f (с подставленным именем ловушки) будет работать на этой конкретной ловушке (второй аргумент, "$f", И вуаля!

... только что понял, что я должен был сначала проверить наличие дубликатов:) . Вот еще один ответ и еще один.

Другие вопросы по тегам