-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
224 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,23 @@ | ||
# bash-trap-stack | ||
command stack for bash traps | ||
# Bash Trap Stack | ||
## Purpose | ||
The traps.sh shell script allows you to create a stack of commands to execute for trap. | ||
## Commands | ||
* traps_start - registers the exit trap | ||
* traps_push $@ - pushes $@ as one entry to the stack | ||
* traps_pop - pops one entry from the stack and execute | ||
* traps_drop - pops one entry from the stack and do nothing | ||
* traps_isEmpty - returns 0 if empty, returns 1 if not empty | ||
* traps_stop - unregisters the exit trap if there is nothing on the stack | ||
* traps_cancel - unregisters the exit trap and remove all entries from the stack | ||
* traps_exit - unregisters the exit map and pops all entries from the stack | ||
* traps_diag - print the stack on pipe 1 | ||
## User Variables | ||
* TRAPS_DEBUG=0 - provides more verbose output on pipe 2 | ||
* TRAPS_SIGNAL=EXIT - controls the trap signal | ||
## Typical Sequence | ||
* traps_start | ||
* traps_push echo "test" | ||
* traps_pop | ||
* traps_stop | ||
## Notes | ||
You can use *set -eE* along with *TRAPS_SIGNAL=ERR* before you start the trap stack to get the function and line number that triggered the trap. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#!/bin/bash | ||
|
||
# SPDX-License-Identifier: MIT | ||
# Copyright (C) 2022 Da Xue | ||
|
||
. traps.sh | ||
|
||
TRAPS_DEBUG=1 | ||
|
||
function traps_test { | ||
traps_start | ||
traps_push "echo" "traps 1" "test 1" "drop" | ||
traps_push "echo" "traps 2" "test 2" "pop" | ||
traps_push "echo" "traps 3" "test 3" "drop" | ||
traps_push "echo" "traps 2" "test 2" "pop" | ||
traps_diag | ||
echo | ||
traps_isEmpty && echo "Empty" || echo "Not Empty" | ||
echo | ||
traps_drop | ||
traps_diag | ||
echo | ||
traps_pop | ||
traps_diag | ||
echo | ||
traps_drop | ||
traps_diag | ||
echo | ||
traps_pop | ||
traps_diag | ||
echo | ||
traps_stop | ||
echo | ||
traps_start | ||
traps_cancel | ||
echo | ||
traps_pop && echo "FAILED" || true | ||
traps_diag | ||
echo | ||
traps_cancel && echo "FAILED" || true | ||
traps_diag | ||
echo | ||
set -eE | ||
TRAPS_SIGNAL=ERR | ||
traps_start | ||
traps_push echo "test" | ||
false | ||
} | ||
|
||
if [ "${BASH_SOURCE[0]##*/}" = "${0##*/}" ]; then | ||
traps_test | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
#!/bin/bash | ||
|
||
# SPDX-License-Identifier: MIT | ||
# Copyright (C) 2022 Da Xue | ||
|
||
TRAPS_DEBUG=0 | ||
TRAPS_SIGNAL=EXIT | ||
|
||
declare -a TRAPS_PARAMS | ||
declare -a TRAPS_LENGTHS | ||
TRAPS_LENGTH= | ||
|
||
function traps_start { | ||
if [ -z "$TRAPS_LENGTH" ]; then | ||
TRAPS_LENGTH=0 | ||
if [ "$TRAPS_SIGNAL" = "ERR" ]; then | ||
trap 'traps_exit "$FUNCNAME" "$LINENO"' $TRAPS_SIGNAL | ||
else | ||
trap traps_exit $TRAPS_SIGNAL | ||
fi | ||
else | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: duplicate call" >&2 | ||
fi | ||
return 1 | ||
fi | ||
} | ||
|
||
function traps_isEmpty { | ||
if [ -z "$TRAPS_LENGTH" ]; then | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: traps not started" >&2 | ||
fi | ||
return 2 | ||
fi | ||
if [ $TRAPS_LENGTH -gt 0 ]; then | ||
return 1 | ||
fi | ||
return 0 | ||
} | ||
|
||
function traps_push { | ||
if [ -z "$TRAPS_LENGTH" ]; then | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: traps not started" >&2 | ||
fi | ||
return 1 | ||
fi | ||
TRAPS_PARAMS+=("$@") | ||
TRAPS_LENGTHS+=($#) | ||
((TRAPS_LENGTH=TRAPS_LENGTH+1)) | ||
} | ||
|
||
function traps_pop { | ||
if [ -z "$TRAPS_LENGTH" ]; then | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: traps not started" >&2 | ||
fi | ||
return 1 | ||
elif [ $TRAPS_LENGTH -gt 0 ]; then | ||
local trap_length=${TRAPS_LENGTHS[@]: -1} | ||
local trap_cmd=(${TRAPS_PARAMS[@]: -$trap_length}) | ||
local traps_params_end=$((${#TRAPS_PARAMS[@]}-trap_length)) | ||
TRAPS_PARAMS=("${TRAPS_PARAMS[@]:0:$traps_params_end}") | ||
TRAPS_LENGTH=$((TRAPS_LENGTH-1)) | ||
TRAPS_LENGTHS=(${TRAPS_LENGTHS[@]:0:$TRAPS_LENGTH}) | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: ${trap_cmd[@]}" >&2 | ||
fi | ||
"${trap_cmd[@]}" | ||
else | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: traps empty" >&2 | ||
fi | ||
return 1 | ||
fi | ||
} | ||
|
||
function traps_drop { | ||
if [ -z "$TRAPS_LENGTH" ]; then | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: traps not started" >&2 | ||
fi | ||
return 1 | ||
elif [ $TRAPS_LENGTH -gt 0 ]; then | ||
local trap_length=${TRAPS_LENGTHS[@]: -1} | ||
local traps_params_end=$((${#TRAPS_PARAMS[@]}-trap_length)) | ||
TRAPS_PARAMS=("${TRAPS_PARAMS[@]:0:$traps_params_end}") | ||
TRAPS_LENGTH=$((TRAPS_LENGTH-1)) | ||
TRAPS_LENGTHS=(${TRAPS_LENGTHS[@]:0:$TRAPS_LENGTH}) | ||
else | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: traps empty" >&2 | ||
fi | ||
return 1 | ||
fi | ||
} | ||
|
||
|
||
function traps_stop { | ||
if [ "$TRAPS_LENGTH" = "0" ]; then | ||
TRAPS_LENGTH= | ||
trap - $TRAPS_SIGNAL | ||
else | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: registered traps" >&2 | ||
traps_diag >&2 | ||
fi | ||
return 1 | ||
fi | ||
} | ||
|
||
function traps_cancel { | ||
if [ -z "$TRAPS_LENGTH" ]; then | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: traps not started" >&2 | ||
fi | ||
return 1 | ||
fi | ||
TRAPS_PARAMS=() | ||
TRAPS_LENGTHS=() | ||
TRAPS_LENGTH= | ||
trap - $TRAPS_SIGNAL | ||
} | ||
|
||
function traps_exit { | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
if [ "$TRAPS_SIGNAL" = "ERR" ]; then | ||
echo "$FUNCNAME: $TRAPS_SIGNAL IN $1 LINE $2" >&2 | ||
fi | ||
fi | ||
trap - $TRAPS_SIGNAL | ||
if [ -z "$TRAPS_LENGTH" ]; then | ||
if [ "$TRAPS_DEBUG" -eq 1 ]; then | ||
echo "$FUNCNAME: traps not initiated" >&2 | ||
fi | ||
return 1 | ||
fi | ||
while [ "$TRAPS_LENGTH" -gt 0 ]; do | ||
traps_pop | ||
done | ||
return 1 | ||
} | ||
|
||
function traps_diag { | ||
echo "$FUNCNAME params: ${TRAPS_PARAMS[@]}" | ||
echo "$FUNCNAME lengths: ${TRAPS_LENGTHS[@]}" | ||
echo "$FUNCNAME length: $TRAPS_LENGTH" | ||
} |