4

Without arguments trap prints the currently set commands for all traps. However, a subshell does not inherit traps, so the canonical example for saving and restoring traps fails in bash:

save_traps=$(trap)
...
eval "$save_traps"

The trap on the RHS of the assignment runs in a subshell, so save_traps is always the empty string. Other than writing the output of trap to a temporary file, how can a script find the current command set for a trap?

Jolta
  • 2,620
  • 1
  • 29
  • 42
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • In the main script, can you `export` the traps to the sub-shells? – Hai Vu Mar 08 '12 at 15:49
  • For what it's worth, even using a temporary file, you can write it as a single command: `trap > trap.$$ && save_traps=$(< trap.$$) && rm trap.$$`. Not quite as terse as `save_traps=$(trap)`, but at least you won't have a temporary file floating around that *whole* time. – ruakh Mar 08 '12 at 16:20
  • @ruakh The problem with the temporary file is that there is no way to ensure it is deleted. Normally, you set a trap to remove the file before you create the file, but that cannot be done here since you lose the previous value of the trap. Writing the command as a one-liner does not avoid the possibility of leaving the temporary file on the filesystem. – William Pursell Mar 08 '12 at 16:59
  • @WilliamPursell: Well, but even setting a trap doesn't *ensure* that the file is deleted, because you can't *ensure* that the trap gets run, and even if it does, you can't *ensure* that it successfully deletes the file. – ruakh Mar 08 '12 at 18:05
  • well, what is the probability that the temp file isn't deleted? And how important is that in your over all system? can't you just do a pre-sweep on trap-tmpfiles at beginning of script OR if your program never stops, have a crontab entry that finds trap-tmpFiles, waits one second, then deletes them? Not pretty, but I think you're up against the trade off of unix processes, and shells. Do you really want to be coding in Java (or other highly proscribed languages? ;-)? My projects usually have low-risk, so with low-probability cases, I let it go. Maybe zsh or rc has something 4 this? Good luck! – shellter Mar 08 '12 at 19:39

2 Answers2

4

Works for me.

Create a sample trap:

$ trap
$ trap echo SIGIO
$ trap
trap -- 'echo' SIGIO

Store the trap into save_traps:

$ save_traps=$(trap)

Remove:

$ trap SIGIO
$ trap | wc -l
   0

Restore:

$ eval "$save_traps"
$ trap
trap -- 'echo' SIGIO

Tested with:

$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)
Copyright (C) 2007 Free Software Foundation, Inc.
Rudolf Adamkovič
  • 31,030
  • 13
  • 103
  • 118
1

Although the Bash manpage seems to say that traps are reset in subshells, and command substitution is executed in a subshell, running trap inside $() works anyway (tested in Bash 3.2 and 4.2). It is also mentioned in POSIX that traps=$(trap) should work.

Thanks to pgas in #bash at irc.freenode.net.

TaylanKammer
  • 5,177
  • 1
  • 19
  • 16