I was playing around with using trap
inside a function because of this question, and came up with this secondary question. Given the following code:
d() {
trap 'return' ERR
false
echo hi
}
If I run d
, the trap
causes the shell to return from the function without printing 'hi'. So far so good. But if I run it a second time, I get a message from the shell:
-bash: return: can only `return' from a function or sourced script
At first, I assumed this meant the ERR sig was happening twice: Once when false
gave a nonzero exit status (inside the function) and again when the function itself returned with a nonzero exit status (outside the function). But that hypothesis doesn't hold up against this test:
e() {
trap 'echo +;return' ERR
false
echo hi
}
If I run the above, no matter how often I run it, I no longer get the can only return
from a function or sourced script warning from bash. Why does the shell treat a compound command different from a simple command in a trap
arg?
My goal was to maintain the actual exit status of the command that caused the function to exit, but I think whatever is causing the above behavior also makes capturing the exit status complicated:
f() {
trap '
local s=$?
echo $s
return $s' ERR
false
echo hi
}
bash> f; echo $?
1
0
Wat? Can someone please explain why $s
expands to two different values here and, if it turns out to be the same cause, the above differentiation between return
and echo +; return
?