Merge nucleic/sleek-thistle-egret-fyej into dev
This commit is contained in:
@@ -0,0 +1,724 @@
|
||||
name: "Builtins: trap"
|
||||
cases:
|
||||
#
|
||||
# trap -l signal listing
|
||||
#
|
||||
- name: "trap -l - lists all signal names"
|
||||
stdin: |
|
||||
# Just verify it outputs something reasonable - check common signals exist
|
||||
trap -l | grep -qE 'HUP|SIGHUP' && echo "has HUP"
|
||||
trap -l | grep -qE 'INT|SIGINT' && echo "has INT"
|
||||
trap -l | grep -qE 'TERM|SIGTERM' && echo "has TERM"
|
||||
|
||||
#
|
||||
# Basic trap registration
|
||||
#
|
||||
- name: "trap registration"
|
||||
stdin: |
|
||||
trap "echo 1" SIGINT
|
||||
trap "echo 2" SIGINT
|
||||
trap -p INT
|
||||
|
||||
trap "echo 3" int
|
||||
trap -p INT
|
||||
|
||||
trap "echo 4" 2
|
||||
trap -p INT
|
||||
|
||||
- name: "trap unregistering"
|
||||
stdin: |
|
||||
echo "[Case 1]"
|
||||
trap "echo 1" SIGINT
|
||||
trap SIGINT
|
||||
trap -p INT
|
||||
|
||||
echo "[Case 2]"
|
||||
trap "echo 2" SIGINT
|
||||
trap - SIGINT
|
||||
trap -p INT
|
||||
|
||||
- name: "trap EXIT"
|
||||
stdin: |
|
||||
trap 'echo "[exit]"' EXIT
|
||||
trap -p EXIT
|
||||
|
||||
- name: "trap EXIT: status code handling"
|
||||
stdin: |
|
||||
trap 'echo "[exit]: \$?: $?"' EXIT
|
||||
trap -p EXIT
|
||||
false
|
||||
|
||||
- name: "trap DEBUG"
|
||||
stdin: |
|
||||
trap 'echo [command: ${BASH_COMMAND}]' DEBUG
|
||||
trap -p DEBUG
|
||||
|
||||
echo First
|
||||
echo Second
|
||||
false
|
||||
|
||||
- name: "trap ERR - registration only"
|
||||
stdin: |
|
||||
trap "echo [err]" ERR
|
||||
trap -p ERR
|
||||
|
||||
- name: "trap ERR - basic invocation"
|
||||
stdin: |
|
||||
trap 'echo "ERR: $?"' ERR
|
||||
false
|
||||
echo "continues"
|
||||
false
|
||||
echo "continues again"
|
||||
|
||||
- name: "trap ERR - not triggered in conditional"
|
||||
stdin: |
|
||||
trap 'echo "ERR trapped"' ERR
|
||||
if false; then
|
||||
echo "then"
|
||||
else
|
||||
echo "else"
|
||||
fi
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - not triggered with && short-circuit"
|
||||
stdin: |
|
||||
trap 'echo "ERR trapped"' ERR
|
||||
false && echo "not printed"
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - not triggered with ||"
|
||||
stdin: |
|
||||
trap 'echo "ERR trapped"' ERR
|
||||
false || echo "fallback"
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - not triggered with negation"
|
||||
stdin: |
|
||||
trap 'echo "ERR trapped"' ERR
|
||||
! false
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - not triggered in while condition"
|
||||
stdin: |
|
||||
trap 'echo "ERR"' ERR
|
||||
while false; do
|
||||
echo "loop body"
|
||||
done
|
||||
echo "after while"
|
||||
|
||||
- name: "trap ERR - not triggered in until condition"
|
||||
stdin: |
|
||||
trap 'echo "ERR"' ERR
|
||||
count=0
|
||||
until false; do
|
||||
((count++))
|
||||
if ((count > 2)); then break; fi
|
||||
done
|
||||
echo "after until"
|
||||
|
||||
- name: "trap ERR - not triggered as part of || list"
|
||||
stdin: |
|
||||
trap 'echo "ERR"' ERR
|
||||
false || true || false
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - not triggered for negated command"
|
||||
stdin: |
|
||||
trap 'echo "ERR"' ERR
|
||||
if ! true; then
|
||||
echo "then"
|
||||
fi
|
||||
! false
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - triggered after && chain completes then fails"
|
||||
stdin: |
|
||||
trap 'echo "ERR trapped"' ERR
|
||||
true && true
|
||||
false
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - execution doesn't affect control flow"
|
||||
stdin: |
|
||||
trap 'echo "ERR"' ERR
|
||||
result=0
|
||||
false || result=$?
|
||||
echo "result: $result"
|
||||
|
||||
- name: "trap ERR - multiple failures trigger multiple traps"
|
||||
stdin: |
|
||||
count=0
|
||||
trap '((count++)); echo "ERR $count"' ERR
|
||||
false
|
||||
false
|
||||
false
|
||||
echo "total: $count"
|
||||
|
||||
- name: "trap ERR - has access to exit status"
|
||||
stdin: |
|
||||
trap 'echo "ERR with status: $?"' ERR
|
||||
(exit 42)
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - has access to BASH_COMMAND"
|
||||
known_failure: true # TODO(traps): ERR trap basic execution not implemented
|
||||
stdin: |
|
||||
trap 'echo "ERR for: $BASH_COMMAND"' ERR
|
||||
nonexistent_command_xyz 2>/dev/null
|
||||
echo "after"
|
||||
|
||||
- name: "trap ERR - has access to LINENO"
|
||||
known_failure: true # TODO(traps): ERR trap basic execution not implemented
|
||||
stdin: |
|
||||
trap 'echo "ERR at line: $LINENO"' ERR
|
||||
false
|
||||
echo "after"
|
||||
|
||||
- name: "return in EXIT trap within function"
|
||||
known_failure: true # TODO(traps): return in trap handler behavior differs
|
||||
stdin: |
|
||||
myfunc() {
|
||||
trap 'return 0' EXIT
|
||||
false
|
||||
echo "should not print in func"
|
||||
}
|
||||
myfunc
|
||||
echo "after func"
|
||||
|
||||
- name: "subshell inherits signal traps (for trap -p display)"
|
||||
stdin: |
|
||||
trap 'echo "[parent int]"' INT
|
||||
trap 'echo "[parent term]"' TERM
|
||||
trap -p INT
|
||||
echo "---"
|
||||
(trap -p INT; trap -p TERM)
|
||||
|
||||
- name: "subshell can override inherited trap"
|
||||
stdin: |
|
||||
trap 'echo "[parent int]"' INT
|
||||
trap -p INT
|
||||
echo "---"
|
||||
(trap 'echo "[subshell int]"' INT; trap -p INT)
|
||||
|
||||
- name: "subshell inherits EXIT trap"
|
||||
stdin: |
|
||||
trap 'echo "[exit]"' EXIT
|
||||
trap -p EXIT
|
||||
echo "---"
|
||||
(trap -p EXIT)
|
||||
|
||||
- name: "subshell inherits DEBUG trap"
|
||||
stdin: |
|
||||
trap 'echo "[debug]"' DEBUG
|
||||
trap -p DEBUG
|
||||
echo "---"
|
||||
(trap -p DEBUG)
|
||||
|
||||
- name: "subshell does not execute inherited DEBUG trap"
|
||||
stdin: |
|
||||
trap 'echo "[debug]"' DEBUG
|
||||
echo "parent"
|
||||
echo "---"
|
||||
(echo "subshell")
|
||||
echo "back in parent"
|
||||
|
||||
- name: "subshell can set its own EXIT trap"
|
||||
known_failure: true # TODO(traps): EXIT trap in subshell
|
||||
stdin: |
|
||||
trap 'echo "[parent exit]"' EXIT
|
||||
echo "parent"
|
||||
(trap 'echo "[subshell exit]"' EXIT; echo "subshell")
|
||||
echo "back in parent"
|
||||
|
||||
- name: "subshell inherited EXIT trap does not fire"
|
||||
stdin: |
|
||||
trap 'echo "[exit]"' EXIT
|
||||
echo "parent"
|
||||
(echo "subshell")
|
||||
echo "back in parent"
|
||||
|
||||
#
|
||||
# Subshell trap inheritance in command substitution
|
||||
#
|
||||
- name: "command substitution inherits signal trap (trap -p display)"
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
result=$(trap -p INT)
|
||||
echo "$result"
|
||||
|
||||
- name: "command substitution does not fire inherited signal trap"
|
||||
known_failure: true # TODO(signals): signal handling in command substitution
|
||||
stdin: |
|
||||
trap 'echo "[int]" >&2' INT
|
||||
result=$(kill -INT $$; echo "after kill")
|
||||
echo "result: $result"
|
||||
|
||||
- name: "command substitution can set its own trap"
|
||||
stdin: |
|
||||
trap 'echo "[parent int]"' INT
|
||||
result=$(trap 'echo "[subshell int]"' INT; trap -p INT)
|
||||
echo "$result"
|
||||
|
||||
- name: "command substitution EXIT trap not inherited from parent"
|
||||
stdin: |
|
||||
trap 'echo "[parent exit]"' EXIT
|
||||
result=$(trap -p EXIT; echo "inside")
|
||||
echo "result: $result"
|
||||
|
||||
- name: "command substitution can have its own EXIT trap"
|
||||
known_failure: true # TODO: EXIT trap in command substitution subshell
|
||||
stdin: |
|
||||
trap 'echo "[parent exit]"' EXIT
|
||||
result=$(trap 'echo "[sub exit]"' EXIT; echo "inside")
|
||||
echo "result: $result"
|
||||
|
||||
- name: "nested command substitution trap inheritance"
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
outer=$(inner=$(trap -p INT); echo "inner: $inner")
|
||||
echo "outer: $outer"
|
||||
|
||||
#
|
||||
# Subshell trap inheritance in pipelines
|
||||
#
|
||||
- name: "pipeline component inherits signal trap (trap -p display)"
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
trap -p INT | cat
|
||||
|
||||
- name: "pipeline component can override trap"
|
||||
stdin: |
|
||||
trap 'echo "[parent int]"' INT
|
||||
{ trap 'echo "[pipe int]"' INT; trap -p INT; } | cat
|
||||
|
||||
- name: "pipeline EXIT trap behavior"
|
||||
stdin: |
|
||||
trap 'echo "[exit]"' EXIT
|
||||
{ trap -p EXIT; echo "in pipe"; } | cat
|
||||
echo "after pipe"
|
||||
|
||||
- name: "multiple pipeline stages trap inheritance"
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
trap -p INT | cat | cat
|
||||
|
||||
#
|
||||
# Subshell trap inheritance in process substitution
|
||||
#
|
||||
- name: "process substitution inherits signal trap"
|
||||
known_failure: true # TODO: process substitution trap inheritance
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
cat <(trap -p INT)
|
||||
|
||||
- name: "process substitution output trap inheritance"
|
||||
skip: true # TODO: process substitution trap inheritance / inconsistent across distros
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
echo "data" > >(trap -p INT; cat > /dev/null)
|
||||
# Give time for the process substitution to complete
|
||||
wait
|
||||
|
||||
- name: "process substitution can set own EXIT trap"
|
||||
known_failure: true # TODO: EXIT trap in process substitution
|
||||
stdin: |
|
||||
trap 'echo "[parent exit]"' EXIT
|
||||
cat <(trap 'echo "[sub exit]"' EXIT; echo "inside")
|
||||
echo "after"
|
||||
|
||||
#
|
||||
# Subshell trap inheritance in background jobs
|
||||
#
|
||||
- name: "background job inherits signal trap (trap -p display)"
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
trap -p INT &
|
||||
wait
|
||||
|
||||
- name: "background job does not fire inherited signal trap"
|
||||
known_failure: true # TODO(signals): background job signal handling
|
||||
stdin: |
|
||||
trap 'echo "[int]" >&2' INT
|
||||
{ kill -INT $$; echo "after kill"; } &
|
||||
wait
|
||||
echo "main done"
|
||||
|
||||
- name: "background job EXIT trap behavior"
|
||||
stdin: |
|
||||
trap 'echo "[exit]"' EXIT
|
||||
{ trap -p EXIT; echo "bg job"; } &
|
||||
wait
|
||||
echo "main continues"
|
||||
|
||||
- name: "background job can set own traps"
|
||||
stdin: |
|
||||
trap 'echo "[parent int]"' INT
|
||||
{ trap 'echo "[bg int]"' INT; trap -p INT; } &
|
||||
wait
|
||||
trap -p INT
|
||||
|
||||
#
|
||||
# Coproc trap inheritance (all coproc tests consolidated here)
|
||||
#
|
||||
# Note: "coproc - inherits signal trap" test is skipped due to bash version
|
||||
# differences. Older bash resets traps in coproc, newer bash (5.3.9) inherits them.
|
||||
# This causes inconsistent test results across CI runners.
|
||||
- name: "coproc - EXIT trap behavior"
|
||||
skip: true # TODO: this test is too inconsistent
|
||||
min_oracle_version: "5.3.0"
|
||||
incompatible_os:
|
||||
- fedora
|
||||
- arch
|
||||
stdin: |
|
||||
trap 'echo "[exit]"' EXIT
|
||||
coproc { trap -p EXIT; echo "coproc"; }
|
||||
cat <&${COPROC[0]}
|
||||
wait
|
||||
echo "main continues"
|
||||
|
||||
- name: "coproc - DEBUG trap inheritance"
|
||||
skip: true # TODO: this test is too inconsistent
|
||||
min_oracle_version: "5.3.0"
|
||||
incompatible_os:
|
||||
- fedora
|
||||
stdin: |
|
||||
trap 'echo "[debug]"' DEBUG
|
||||
coproc { trap -p DEBUG; echo "coproc"; }
|
||||
cat <&${COPROC[0]}
|
||||
wait
|
||||
|
||||
- name: "coproc - ERR trap with errtrace"
|
||||
skip: true # TODO: this test is too inconsistent
|
||||
min_oracle_version: "5.3.0"
|
||||
incompatible_os:
|
||||
- fedora
|
||||
- arch
|
||||
stdin: |
|
||||
set -E
|
||||
trap 'echo "[err]"' ERR
|
||||
coproc { trap -p ERR; false; echo "after false"; }
|
||||
cat <&${COPROC[0]}
|
||||
wait
|
||||
|
||||
#
|
||||
# RETURN trap - basic behavior
|
||||
#
|
||||
- name: "RETURN trap - fires on function return"
|
||||
stdin: |
|
||||
trap 'echo "[return]"' RETURN
|
||||
myfunc() {
|
||||
echo "in func"
|
||||
}
|
||||
myfunc
|
||||
echo "after func"
|
||||
|
||||
- name: "RETURN trap - fires with return value"
|
||||
stdin: |
|
||||
trap 'echo "[return: $?]"' RETURN
|
||||
myfunc() {
|
||||
echo "in func"
|
||||
return 42
|
||||
}
|
||||
myfunc
|
||||
echo "after func"
|
||||
|
||||
- name: "RETURN trap - fires on sourced script completion"
|
||||
known_failure: true # TODO(traps): RETURN trap not firing for sourced scripts
|
||||
test_files:
|
||||
- path: "sourced.sh"
|
||||
contents: |
|
||||
echo "in sourced"
|
||||
stdin: |
|
||||
trap 'echo "[return]"' RETURN
|
||||
. ./sourced.sh
|
||||
echo "after source"
|
||||
|
||||
- name: "RETURN trap - not inherited in function without functrace"
|
||||
stdin: |
|
||||
set +T
|
||||
trap 'echo "[return]"' RETURN
|
||||
outer() {
|
||||
inner() {
|
||||
echo "in inner"
|
||||
}
|
||||
inner
|
||||
echo "after inner"
|
||||
}
|
||||
outer
|
||||
echo "done"
|
||||
|
||||
- name: "RETURN trap - inherited with functrace"
|
||||
known_failure: true # TODO(traps): RETURN trap inheritance with functrace not implemented
|
||||
stdin: |
|
||||
set -T
|
||||
trap 'echo "[return: ${FUNCNAME[0]:-main}]"' RETURN
|
||||
outer() {
|
||||
inner() {
|
||||
echo "in inner"
|
||||
}
|
||||
inner
|
||||
echo "after inner"
|
||||
}
|
||||
outer
|
||||
echo "done"
|
||||
|
||||
- name: "RETURN trap - in explicit subshell"
|
||||
stdin: |
|
||||
trap 'echo "[return]"' RETURN
|
||||
(
|
||||
myfunc() { echo "in func"; }
|
||||
myfunc
|
||||
)
|
||||
echo "after subshell"
|
||||
|
||||
- name: "RETURN trap - does not fire for regular commands"
|
||||
stdin: |
|
||||
trap 'echo "[return]"' RETURN
|
||||
echo "cmd1"
|
||||
echo "cmd2"
|
||||
true
|
||||
echo "done"
|
||||
|
||||
- name: "RETURN trap - does not fire for subshell completion"
|
||||
stdin: |
|
||||
trap 'echo "[return]"' RETURN
|
||||
(echo "in subshell")
|
||||
echo "after subshell"
|
||||
|
||||
#
|
||||
# Signal trap execution verification
|
||||
#
|
||||
- name: "trap SIGUSR1"
|
||||
known_failure: true # TODO(signals): signal handling
|
||||
stdin: |
|
||||
trap 'echo "[usr1 received]"' USR1
|
||||
trap -p USR1
|
||||
kill -USR1 $$
|
||||
echo "after signal"
|
||||
|
||||
- name: "trap SIGUSR2"
|
||||
known_failure: true # TODO(signals): signal handling
|
||||
stdin: |
|
||||
trap 'echo "[usr2 received]"' SIGUSR2
|
||||
trap -p USR2
|
||||
kill -USR2 $$
|
||||
echo "after signal"
|
||||
|
||||
- name: "trap multiple signals with same handler"
|
||||
known_failure: true # TODO(signals): signal handling
|
||||
stdin: |
|
||||
trap 'echo "[signal received]"' USR1 USR2
|
||||
kill -USR1 $$
|
||||
kill -USR2 $$
|
||||
echo "done"
|
||||
|
||||
- name: "trap handler can inspect signal"
|
||||
known_failure: true # TODO(signals): signal handling
|
||||
stdin: |
|
||||
handler() {
|
||||
echo "handler called"
|
||||
}
|
||||
trap handler USR1
|
||||
kill -USR1 $$
|
||||
echo "after"
|
||||
|
||||
#
|
||||
# Trap reset and unset
|
||||
#
|
||||
- name: "trap - clears trap"
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
trap -p INT
|
||||
trap - INT
|
||||
trap -p INT
|
||||
|
||||
- name: "trap '' ignores signal"
|
||||
known_failure: true # TODO(signals): signal handling
|
||||
stdin: |
|
||||
trap '' INT
|
||||
trap -p INT
|
||||
kill -INT $$
|
||||
echo "survived"
|
||||
|
||||
- name: "trap with empty string can be cleared"
|
||||
stdin: |
|
||||
trap '' INT
|
||||
trap -p INT
|
||||
trap - INT
|
||||
trap -p INT
|
||||
|
||||
#
|
||||
# trap -p edge cases
|
||||
#
|
||||
- name: "trap -p - with no args shows all traps"
|
||||
stdin: |
|
||||
trap 'echo a' INT
|
||||
trap 'echo b' TERM
|
||||
trap 'echo c' EXIT
|
||||
trap -p | sort
|
||||
|
||||
- name: "trap -p - with specific signal"
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
trap 'echo "[term]"' TERM
|
||||
trap -p INT
|
||||
trap -p TERM
|
||||
|
||||
- name: "trap -p - with multiple signals"
|
||||
stdin: |
|
||||
trap 'echo "[int]"' INT
|
||||
trap 'echo "[term]"' TERM
|
||||
trap 'echo "[usr1]"' USR1
|
||||
trap -p INT TERM USR1
|
||||
|
||||
- name: "trap -p - for unset trap shows nothing"
|
||||
stdin: |
|
||||
trap -p INT
|
||||
echo "done"
|
||||
|
||||
- name: "trap -p - output is re-executable"
|
||||
stdin: |
|
||||
trap 'echo "hello world"' INT
|
||||
eval "$(trap -p INT)"
|
||||
trap -p INT
|
||||
|
||||
#
|
||||
# Trap handler quoting
|
||||
#
|
||||
- name: "trap handler - single quotes preserved"
|
||||
known_failure: true # TODO(traps): quote escaping in trap -p output differs
|
||||
stdin: |
|
||||
trap 'echo '\''quoted'\''' INT
|
||||
trap -p INT
|
||||
|
||||
- name: "trap handler - double quotes in handler"
|
||||
stdin: |
|
||||
trap 'echo "double quoted"' INT
|
||||
trap -p INT
|
||||
|
||||
- name: "trap handler - special characters"
|
||||
stdin: |
|
||||
trap 'echo $HOME; echo "done"' INT
|
||||
trap -p INT
|
||||
|
||||
- name: "trap handler - newlines in handler"
|
||||
stdin: |
|
||||
trap 'echo line1
|
||||
echo line2' INT
|
||||
trap -p INT
|
||||
|
||||
#
|
||||
# DEBUG trap - basic behavior
|
||||
#
|
||||
- name: "DEBUG trap - sees BASH_COMMAND"
|
||||
known_failure: true # TODO(BASH_COMMAND): not showing assignment, quotes differ
|
||||
stdin: |
|
||||
trap 'echo "cmd: $BASH_COMMAND"' DEBUG
|
||||
x=1
|
||||
echo "x is $x"
|
||||
|
||||
- name: "DEBUG trap - sees LINENO"
|
||||
known_failure: true # TODO(traps): LINENO in DEBUG trap not accurate
|
||||
stdin: |
|
||||
trap 'echo "line: $LINENO"' DEBUG
|
||||
echo first
|
||||
echo second
|
||||
|
||||
- name: "DEBUG trap - fires before each simple command"
|
||||
known_failure: true # TODO(traps): DEBUG trap not firing for trap command itself
|
||||
stdin: |
|
||||
count=0
|
||||
trap '((count++))' DEBUG
|
||||
echo a
|
||||
echo b
|
||||
echo c
|
||||
echo "count: $count"
|
||||
|
||||
- name: "DEBUG trap - in loop"
|
||||
known_failure: true # TODO(BASH_COMMAND): quotes differ
|
||||
stdin: |
|
||||
trap 'echo "[debug: $BASH_COMMAND]"' DEBUG
|
||||
for i in 1 2; do
|
||||
echo "iter $i"
|
||||
done
|
||||
|
||||
#
|
||||
# EXIT trap - advanced cases
|
||||
#
|
||||
- name: "EXIT trap - has access to exit status"
|
||||
stdin: |
|
||||
trap 'echo "exiting with: $?"' EXIT
|
||||
exit 42
|
||||
|
||||
- name: "EXIT trap - runs even after errexit"
|
||||
stdin: |
|
||||
set -e
|
||||
trap 'echo "[exit trap ran]"' EXIT
|
||||
false
|
||||
echo "not reached"
|
||||
|
||||
- name: "EXIT trap - can modify exit status"
|
||||
known_failure: true # TODO(traps): EXIT trap exit doesn't modify status
|
||||
stdin: |
|
||||
trap 'exit 0' EXIT
|
||||
exit 99
|
||||
|
||||
- name: "EXIT trap - multiple assignments last one wins"
|
||||
stdin: |
|
||||
trap 'echo "first"' EXIT
|
||||
trap 'echo "second"' EXIT
|
||||
echo "done"
|
||||
|
||||
#
|
||||
# EXIT trap in -c mode
|
||||
#
|
||||
- name: "EXIT trap fires in -c mode"
|
||||
args:
|
||||
- "-c"
|
||||
- "trap 'echo exiting' EXIT; echo hello"
|
||||
expected_stdout: |
|
||||
hello
|
||||
exiting
|
||||
|
||||
- name: "EXIT trap in -c mode has access to exit status"
|
||||
args:
|
||||
- "-c"
|
||||
- "trap 'echo \"status: $?\"' EXIT; exit 42"
|
||||
expected_stdout: "status: 42\n"
|
||||
|
||||
- name: "EXIT trap in -c mode runs after errexit"
|
||||
args:
|
||||
- "-c"
|
||||
- "set -e; trap 'echo trapped' EXIT; false"
|
||||
expected_stdout: "trapped\n"
|
||||
|
||||
- name: "EXIT trap in -c mode with multiple assignments last one wins"
|
||||
args:
|
||||
- "-c"
|
||||
- "trap 'echo first' EXIT; trap 'echo second' EXIT; echo done"
|
||||
expected_stdout: |
|
||||
done
|
||||
second
|
||||
|
||||
#
|
||||
# Trap with multiple signals
|
||||
#
|
||||
- name: "trap - clear multiple signals at once"
|
||||
stdin: |
|
||||
trap 'echo "[handler]"' INT TERM USR1
|
||||
trap -p INT
|
||||
trap -p TERM
|
||||
trap -p USR1
|
||||
echo "---"
|
||||
trap - INT TERM USR1
|
||||
trap -p INT
|
||||
trap -p TERM
|
||||
trap -p USR1
|
||||
echo "done"
|
||||
|
||||
- name: "trap - ignore multiple signals"
|
||||
stdin: |
|
||||
trap '' INT TERM
|
||||
trap -p INT
|
||||
trap -p TERM
|
||||
echo "done"
|
||||
Reference in New Issue
Block a user