The following issue has been UPDATED.
======================================================================
http://austingroupbugs.net/view.php?id=53
======================================================================
Reported By: geoffclare
Assigned To: ajosey
======================================================================
Project: 1003.1(2008)/Issue 7
Issue ID: 53
Category: Shell and Utilities
Type: Error
Severity: Objection
Priority: normal
Status: Resolved
Name: Geoff Clare
Organization: The Open Group
User Reference:
Section: 2.14
Page Number: 2368
Line Number: 74879
Final Accepted Text: Note 0000094
Resolution: Accepted As Marked
Fixed in Version:
======================================================================
Date Submitted: 2009-06-25 13:46 MST
Last Modified: 2009-06-26 08:51 MST
======================================================================
Summary: trap in a subshell
Description:
The description of the trap utility states:
When a subshell is entered, traps that are not being ignored are
set to the default actions.
It then goes on to state requirements about the output of trap with
no arguments, including the example:
save_traps=$(trap)
...
eval "$save_traps"
However, in this example when trap is executed in the command
substitution it is in a subshell, and therefore (according to the
first quote above) $save_traps will not include traps that are not
being ignored. The eval will only restore the traps being ignored.
This does not match existing practice: the example "works" in
current shells. However, they seem to use two different solutions.
Most shells try to decide whether the purpose of the command
substitution is to query the current traps, and if so they don't
alter the traps. However, they are not very good at it - things
like:
var=trap; save_traps=$($var)
or even:
save_traps=$(trap; true)
don't work. The other solution (used only by ksh93 out of the
shells I tried) is that a trap command without operands in a subshell
doesn't report the current traps - it reports the traps that were in
effect immediately before the current subshell environment was
entered, unless a trap command with operands has subsequently been
executed.
Both solutions have disadvantages. The first, as can be seen
from the examples above, may give the wrong output in cases other
than a straight $(trap) or `trap`. The second gives misleading
output when trying to report the current trap settings from
within a subshell (although saving them to a variable in a
subshell works because trap in the lower subshell reports the
traps that were in effect in the higher subshell).
In both cases the number of applications affected is likely to be
very small. (With the second, the problem doesn't so much affect
the applications themselves as application writers trying to
debug the trap handling in their scripts.)
There are several ways this could be fixed in the standard:
1. Allow both solutions. (Making the standard match existing practice.)
2. Allow the first solution only. (Making the standard match existing
practice on certified systems.)
3. Allow the second solution only. (Eliminating the dubious practice
of trying to identify when a command substitution is being used to
query the current traps.)
4. Require something else, such as a precise specification of the
detection performed in the first solution, or a variation of the second
solution where it only applies to command substitutions not to all
subshells.
5. As 1, 2 or 3 but also add in FUTURE DIRECTIONS that a future
revision may require 4.
Wording changes are proposed below for options 1, 2 and 3. They also
include a minor fix changing "no arguments" to "no operands".
Finally, a warning to anyone who wishes to investigate the behaviour
of ksh93: ensure you don't end your test script with the subshell you
are testing. Follow it with another command such as "echo done".
Otherwise, ksh93 uses an optimisation whereby it doesn't set up the
subshell environment, and this alters the results. (My thanks to
David Korn for pointing this out to me. He also acknowledged that
the effect of this optimisation on traps is a bug in ksh93.)
Desired Action:
Option 1:
Change
"When a subshell is entered, traps that are not being ignored are
set to the default actions."
to
"When a subshell is entered, traps that are not being ignored shall
be set to the default actions, except in the case of a command
substitution containing only a single trap command, when the traps
need not be altered. Implementations may check for this case
using only lexical analysis; for example if `trap` and $( trap -- )
do not alter the traps in the subshell, cases such as assigning
var=trap and then using $($var) may still alter them."
Change
"The trap command with no arguments shall write to standard output
a list of commands associated with each condition."
to
"The trap command with no operands shall write to standard output
a list of commands associated with each condition. If the command
is executed in a subshell, the implementation does not perform
the optional check described above for a command substitution
containing only a single trap command, and no trap commands with
operands have been executed since entry to the subshell, the list
shall contain the commands that were associated with each
condition immediately before the subshell environment was entered.
Otherwise, the list shall contain the commands currently
associated with each condition."
Option 2:
Change
"When a subshell is entered, traps that are not being ignored are
set to the default actions."
to
"When a subshell is entered, traps that are not being ignored shall
be set to the default actions, except in the case of a command
substitution containing only a single trap command, when the traps
shall not be altered. Implementations may check for this case
using only lexical analysis; for example `trap` and $( trap -- )
are required not to alter the traps in the subshell, whereas if
the assignment var=trap has previously been made, $($var) may
alter them."
Change
"The trap command with no arguments shall write ..."
to
"The trap command with no operands shall write ..."
Option 3:
Change
"The trap command with no arguments shall write to standard output
a list of commands associated with each condition."
to
"The trap command with no operands shall write to standard output
a list of commands associated with each condition. If the command
is executed in a subshell and no trap commands with operands have
been executed since entry to the subshell, the list shall contain
the commands that were associated with each condition immediately
before the subshell environment was entered. Otherwise, the list
shall contain the commands currently associated with each
condition."
======================================================================
----------------------------------------------------------------------
(0000093) Don Cragun (manager) - 2009-06-26 06:25
http://austingroupbugs.net/view.php?id=53#c93
----------------------------------------------------------------------
Originally reported by gwc:xxxxxxxxxxxxx
Thu, 19 Mar 2009 11:15:35 +0000
with Subject: Defect in XCU 2.14 trap
Transcribed by Don Cragun from xcubug3.txt ERN 9
Submitter tag "gwc trap in subshell"
----------------------------------------------------------------------
(0000094) Don Cragun (manager) - 2009-06-25 13:53
http://austingroupbugs.net/view.php?id=53#c94
----------------------------------------------------------------------
Apply Option 1 in Desired Action field
|