Last active
April 6, 2022 02:53
-
-
Save Lucretiel/c1094aad1572571c349ae3266d173b35 to your computer and use it in GitHub Desktop.
Trap a command in bash without removing the previous trap command
This file contains hidden or 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
#!/bin/bash | |
# This function adds an additional command to the trap stack. Each command | |
# added in this way will be called in reverse order when the signal is received. | |
# | |
# This function works with a simple concatenation with the currently existing | |
# trap function. Popping something from the trap stack without running it is | |
# left as an exercise to the reader; it requires at least a parser capable of | |
# matching { } correctly. | |
# | |
# Usage: `add_trap <COMMAND> <SIGNAL>` | |
# | |
# THIS FUNCTION DOES NOT SUPPORT MUTLILINE COMMANDS OR COMMANDS WITH ANY | |
# SINGLE QUOTES, EVEN IF THEY'RE ESCAPED, SO DON'T TRY IT | |
add_trap() { | |
# Check for --help | |
for arg in "$@" | |
do | |
case "$arg" in | |
'-h' | '--help' ) | |
echo "Usage: add_trap <COMMAND> <REASON>" | |
echo | |
echo "Push a COMMAND on to the trap stack; this COMMAND will be run before and in addition to any other current trap commands for the given REASON" | |
return 0 | |
esac | |
done | |
# Check number of arguments | |
if test "$#" -gt 2 | |
then | |
{ | |
echo "Error: more than two argument given. Did you forget to enclose your COMMAND in quotes?" | |
echo | |
echo "Usage: add_trap <COMMAND> <REASON>" | |
} >&2 | |
return 1 | |
fi | |
# Strip trailing whitespace and semicolons from the command | |
COMMAND="$(echo "$1" | sed -e 's/^\(.*[^;\s]\)[; ]*$/\1/g')" | |
TRAP="$2" | |
# Test that we have a command | |
if test -z "$COMMAND" | |
then | |
{ | |
echo "Error: need a command to trap with" | |
echo | |
echo "Usage: add_trap <COMMAND> <REASON>" | |
} >&2 | |
return 1 | |
fi | |
# Test that we have a signal or reason to trap on | |
if test -z "$TRAP" | |
then | |
{ | |
echo "Error: need a signal or other reason to trap on (such as EXIT or SIGINT)" | |
echo | |
echo "Usage: add_trap <COMMAND> <REASON>" | |
} >&2 | |
return 1 | |
fi | |
# Check no single quotes in $COMMAND | |
if echo "$COMMAND" | grep -q "'" | |
then | |
echo "can't add commands with single quote characters" | |
return 1 | |
fi | |
# TODO: detect and reject multiline commands | |
CURRENT_TRAP="$(trap -p "$TRAP" | grep -o -P "(?<=-- ').*(?=' EXIT)")" | |
trap "{ $COMMAND ; } ; $CURRENT_TRAP" "$TRAP" | |
} | |
# Same as above, but without correctness checking | |
add_trap_unchecked() { | |
COMMAND="$1" | |
TRAP="$2" | |
CURRENT_TRAP="$(trap -p "$TRAP" | grep -o -P "(?<=-- ').*(?=' EXIT)")" | |
trap "{ $COMMAND ; } ; $CURRENT_TRAP" "$TRAP" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment