I've noticed that when Bash is called as sh
, you cannot unset a trap using e.g., trap -- EXIT
, but when it is called as bash
you can.
trap - EXIT
seems to work regardless of how the shell was called.
Example output:
[vagrant@localhost ~]$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 9 2016 /bin/sh -> bash
[vagrant@localhost ~]$ sh
sh-4.1$ trap 'echo something' EXIT
sh-4.1$ exit
exit
something
[vagrant@localhost ~]$ sh
sh-4.1$ trap 'echo something' EXIT
sh-4.1$ trap -- EXIT
trap: usage: trap [-lp] [[arg] signal_spec ...]
sh-4.1$ trap - EXIT
sh-4.1$ exit
exit
[vagrant@localhost ~]$ bash
[vagrant@localhost ~]$ trap 'echo something' EXIT
[vagrant@localhost ~]$ exit
exit
something
[vagrant@localhost ~]$ bash
[vagrant@localhost ~]$ trap 'echo something' EXIT
[vagrant@localhost ~]$ trap -- EXIT
[vagrant@localhost ~]$ exit
exit
[vagrant@localhost ~]$ bash
[vagrant@localhost ~]$ trap 'echo something' EXIT
[vagrant@localhost ~]$ trap - EXIT
[vagrant@localhost ~]$ exit
exit
[vagrant@localhost ~]$
I checked the documentation but I don't see the difference elucidated anywhere. I do see that the single hyphen form is specified by POSIX.
Is there any difference in behavior between the two methods of unsetting a trap, other than --
not working in sh
?
1 Answer 1
This is explained some in the trap(1P) man page and more in the Advanced Bash Scripting Guide, which explains that the --
is a Bash built-in, used to denote the "end of options" for a command. Since scripts using sh
are designed to be portable between other systems with it, bash behaves as if it were executed with --posix
, which changes some shell behavior to match the POSIX specification.
When a signal is "trapped", (e.g., EXIT
), it binds the first argument after the command to the signal, eval
-ing it when the signal is issued, and ignoring its normal behavior (except for EXIT
). So when trap 'echo something' EXIT
is run, then exit
, the shell will eval 'echo something'
prior to exiting. This would also work with a different signal, such as TERM
, which could be bound to, for example, a graceful exit function in a script. When trap -- EXIT
is run, the --
is interpreted as an "end of arguments", indicating to trap
that the signal is to be bound to null (''
) (since there were no flags prior to or after --
), indicating to the shell to ignore the signal (however, this doesn't work with EXIT, but works with other signals). Running trap -- 'echo something' EXIT
, however, will still eval 'echo something'
and exit upon exit
. As per the specification of trap
, the command -
by itself indicates that the shell will reset any traps for the signals specified, which is why it works in both sh
and Bash.
-
Interesting. So it seems that there is a difference, if the trap(s) that will be reset by
trap - EXIT
are different from a null trap?Wildcard– Wildcard2017年01月13日 22:40:37 +00:00Commented Jan 13, 2017 at 22:40 -
1