Поиск…


Синтаксис

  • trap action sigspec ... # Запустить «действие» в списке сигналов
  • trap sigspec ... # Опуская действие сбрасывает ловушки для сигналов

параметры

параметр Имея в виду
-п Список установленных ловушек
-l Имена списков и соответствующие номера

замечания

Утилита trap - специальная встроенная оболочка. Он определен в POSIX , но bash добавляет некоторые полезные расширения.

Примеры, совместимые с POSIX, начинаются с #!/bin/sh , а примеры, начинающиеся с #!/bin/bash используют расширение bash.

Сигналами могут быть либо номер сигнала, имя сигнала (без префикса SIG), либо специальное ключевое слово EXIT .

Гарантируются POSIX:

Число название Заметки
0 ВЫХОД Всегда запускать на выходе оболочки, независимо от кода выхода
1 SIGHUP
2 SIGINT Это то, что посылает ^C
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM Это то, что kill по умолчанию

Захват SIGINT или Ctl + C

Ловушка сбрасывается для подоболочек, поэтому sleep будет по-прежнему действовать на сигнал SIGINT отправленный ^C (обычно путем выхода из игры), но родительский процесс (то есть сценарий оболочки) не будет.

#!/bin/sh

# Run a command on signal 2 (SIGINT, which is what ^C sends)
sigint() {
    echo "Killed subshell!"
}
trap sigint INT

# Or use the no-op command for no output
#trap : INT

# This will be killed on the first ^C
echo "Sleeping..."
sleep 500

echo "Sleeping..."
sleep 500

И вариант, который по-прежнему позволяет вам выйти из основной программы, дважды нажав ^C дважды:

last=0
allow_quit() {
    [ $(date +%s) -lt $(( $last + 1 )) ] && exit
    echo "Press ^C twice in a row to quit"
    last=$(date +%s)
}
trap allow_quit INT

Введение: очистка временных файлов

Вы можете использовать команду trap для «ловушки» сигналов; это эквивалент оболочки signal() или sigaction() в C и большинстве других языков программирования для улавливания сигналов.

Одним из наиболее распространенных способов использования trap является очистка временных файлов как от ожидаемого, так и от неожиданного выхода.

К сожалению, недостаточно скриптов оболочки делают следующее :-(

#!/bin/sh

# Make a cleanup function
cleanup() {
  rm --force -- "${tmp}"
}

# Trap the special "EXIT" group, which is always run when the shell exits.
trap cleanup EXIT

# Create a temporary file
tmp="$(mktemp -p /tmp tmpfileXXXXXXX)"

echo "Hello, world!" >> "${tmp}"

# No rm -f "$tmp" needed. The advantage of using EXIT is that it still works
# even if there was an error or if you used exit.

Накопите список ловушек для работы при выходе.

Вы когда-нибудь забыли добавить trap для очистки временного файла или выполнить другую работу при выходе?

Вы когда-нибудь устанавливали одну ловушку, которая отменяла другую?

Этот код упрощает добавление вещей, которые нужно выполнять при выходе из одного элемента за раз, вместо того, чтобы иметь один большой оператор trap где-то в вашем коде, что может быть легко забыть.

# on_exit and add_on_exit
# Usage:
#   add_on_exit rm -f /tmp/foo
#   add_on_exit echo "I am exiting"
#   tempfile=$(mktemp)
#   add_on_exit rm -f "$tempfile"
# Based on http://www.linuxjournal.com/content/use-bash-trap-statement-cleanup-temporary-files
function on_exit()
{
    for i in "${on_exit_items[@]}"
    do
        eval $i
    done
}
function add_on_exit()
{
    local n=${#on_exit_items[*]}
    on_exit_items[$n]="$*"
    if [[ $n -eq 0 ]]; then
        trap on_exit EXIT
    fi
}

Убийство детских процессов на выходе

Выражения Trap не должны быть отдельными функциями или программами, они также могут быть более сложными выражениями.

Объединив jobs -p и kill , мы можем убить все порожденные дочерние процессы оболочки при выходе:

trap 'jobs -p | xargs kill' EXIT

реагировать на изменение размера окна терминала

Существует сигнал WINCH (WINdowCHange), который запускается при изменении размера окна терминала.

declare -x rows cols
 
update_size(){
  rows=$(tput lines) # get actual lines of term
  cols=$(tput cols)  # get actual columns of term
  echo DEBUG terminal window has no $rows lines and is $cols characters wide
}

trap update_size WINCH


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow