保存和恢复陷阱状态? 简单的方法来管理多个处理程序陷阱?(Save and restore tr

2019-08-31 14:51发布

什么是覆盖一个好办法bash陷阱处理程序不会永久践踏,可能会或可能尚未设置现有的? 怎么样动态管理陷阱程序的任意链?

有没有办法救陷阱处理程序的当前状态,这样他们就可以在以后恢复?

Answer 1:

保存和恢复猛砸你的陷阱处理程序状态

我想提出以下栈的实现,以跟踪和恢复陷阱状态。 使用这种方法,我能推陷阱更改,然后弹出他们离开时,我要和他们一起做。 这也可以用来链许多陷阱例行程序一起。

请参阅下面的源文件(.trap_stack.sh)

#!/bin/bash
trap_stack_name() {
  local sig=${1//[^a-zA-Z0-9]/_}
  echo "__trap_stack_$sig"
}

extract_trap() {
  echo ${@:3:$(($#-3))}
}

get_trap() {
  eval echo $(extract_trap `trap -p $1`)
}

trap_push() {
  local new_trap=$1
  shift
  local sigs=$*
  for sig in $sigs; do
    local stack_name=`trap_stack_name "$sig"`
    local old_trap=$(get_trap $sig)
    eval "${stack_name}"'[${#'"${stack_name}"'[@]}]=$old_trap'
    trap "${new_trap}" "$sig"
  done
}

trap_pop() {
  local sigs=$*
  for sig in $sigs; do
    local stack_name=`trap_stack_name "$sig"`
    local count; eval 'count=${#'"${stack_name}"'[@]}'
    [[ $count -lt 1 ]] && return 127
    local new_trap
    local ref="${stack_name}"'[${#'"${stack_name}"'[@]}-1]'
    local cmd='new_trap=${'"$ref}"; eval $cmd
    trap "${new_trap}" "$sig"
    eval "unset $ref"
  done
}

trap_prepend() {
  local new_trap=$1
  shift
  local sigs=$*
  for sig in $sigs; do
    if [[ -z $(get_trap $sig) ]]; then
      trap_push "$new_trap" "$sig"
    else
      trap_push "$new_trap ; $(get_trap $sig)" "$sig"
    fi
  done
}

trap_append() {
  local new_trap=$1
  shift
  local sigs=$*
  for sig in $sigs; do
    if [[ -z $(get_trap $sig) ]]; then
      trap_push "$new_trap" "$sig"
    else
      trap_push "$(get_trap $sig) ; $new_trap" "$sig"
    fi
  done
}

这可以管理被定义为这样的例子定义的命名功能,还即席程序句柄trap "kill $!" SIGTERM SIGINT trap "kill $!" SIGTERM SIGINT

这是测试脚本我以前帮我写它:

#!/bin/bash
source .trap_stack.sh

initial_trap='echo "messy" ;'" echo 'handler'"
non_f_trap='echo "non-function trap"'
f_trap() {
  echo "function trap"
}

print_status() {
  echo "    SIGINT  trap: `get_trap SIGINT`"  
  echo "    SIGTERM trap: `get_trap SIGTERM`"
  echo "-------------"
  echo
}

echo "--- TEST START ---"
echo "Initial trap state (should be empty):"
print_status

echo 'Setting messy non-function handler for SIGINT ("original state")'
trap "$initial_trap" SIGINT
print_status

echo 'Pop empty stacks (still in original state)'
trap_pop SIGINT SIGTERM
print_status

echo 'Push non-function handler for SIGINT'
trap_push "$non_f_trap" SIGINT
print_status

echo 'Append function handler for SIGINT and SIGTERM'
trap_append f_trap SIGINT SIGTERM
print_status

echo 'Prepend function handler for SIGINT and SIGTERM'
trap_prepend f_trap SIGINT SIGTERM
print_status

echo 'Push non-function handler for SIGINT and SIGTERM'
trap_push "$non_f_trap" SIGINT SIGTERM
print_status

echo 'Pop both stacks'
trap_pop SIGINT SIGTERM
print_status

echo 'Prepend function handler for SIGINT and SIGTERM'
trap_prepend f_trap SIGINT SIGTERM
print_status

echo 'Pop both stacks thrice'
trap_pop SIGINT SIGTERM
trap_pop SIGINT SIGTERM
trap_pop SIGINT SIGTERM
print_status

echo 'Push non-function handler for SIGTERM'
trap_push "$non_f_trap" SIGTERM
print_status

echo 'Pop handler state for SIGINT (SIGINT is now back to original state)'
trap_pop SIGINT
print_status

echo 'Pop handler state for SIGTERM (SIGTERM is now back to original state)'
trap_pop SIGTERM
print_status


文章来源: Save and restore trap state? Easy way to manage multiple handlers for traps?