Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001876 [1003.1(2024)/Issue8] Shell and Utilities Editorial Clarification Requested 2024-11-18 23:54 2024-11-23 03:32
Reporter calestyo View Status public  
Assigned To
Priority normal Resolution Open  
Status New  
Name Christoph Anton Mitterer
Organization
User Reference
Section 2.15 Special Built-In Utilities
Page Number 2554
Line Number 83295, ff.
Interp Status ---
Final Accepted Text
Summary 0001876: clarify, whether a trap action that is executed from a context where set -e is ignored, would have set -e ignored, too
Description Hey.

I've posted this earlier on the list with no result:
https://collaboration.opengroup.org/operational/mailarch.php?soph=N&action=show&archive=austin-group-l&num=37855&limit=100&offset=0&sid= [^]

The question is, whether a trap action that is executed while the shell is in a context in which the effects of set -e are ignored, would also cause the same (i.e. ignoring set -e) in the trap action... or whether this is unspecified (than that should be explicitly mentioned).

I couldn't find anything in the standard from which I'd say the answer to that question follows.

Page 2554, lines 83299-83308 give the exceptions in which set -e is ignored:
> 1. The failure of any individual command in a
> multi-command pipeline, or of any subshell
> environments in which command substitution
> was performed during word expansion, shall
> not cause the shell to exit. Only the failure
> of the pipeline itself shall be considered.
> 2. The -e setting shall be ignored when executing
> the compound list following the while, until,
> if, or elif reserved word, a pipeline
> beginning with the ! reserved word, or any
> command of an AND-OR list other than the last.
> 3. If the exit status of a compound command other
> than a subshell command was the result of a
> failure while -e was being ignored, then -e
> shall not apply to this command.


It follows from that, that set -e is ignored on the `false` in the following example:
  set -e
  foo() { echo a; false; echo b; }
  foo || :
whereas it is not when just calling:
  foo


Page 2565, lines 83708-83710 say:
> The environment in which the shell executes a trap
> action on EXIT shall be identical to the environment
> immediately after the last command executed before
> the trap action on EXIT was executed.

From page 2522, line 82167, which says that:
> Options turned on at invocation or by set
are part of the shell execution environment, one could argue that the whether or not set -e is ignored, applies to an EXIT trap action.
One could however also argue that the standard says explicitly that only options turned ON AT INVOCATION or BY SET are part of it, and that the "ignored set -e" behaviour does not really fall under that-

For the signals I couldn't find anything about the environment in which the trap action is executed, only page 2521, lines 82148-82153:
> When a signal for which a trap has been set is
> received while the shell is waiting for the completion
> of a utility executing a foreground command, the trap
> associated with that signal shall not be executed until
> after the foreground command has completed. When the
> shell is waiting, by means of the wait utility, for
> asynchronous commands to complete, the reception of a
> signal for which a trap has been set shall cause the
> wait utility to return immediately with an exit
> status >128, immediately after which the trap associated
> with that signal shall be taken.

But that doesn't tell which env.

Anyway, some test case seems to imply that at least bash and dash do NOT ignore the effects of set -e, even when the signal is handled at a context where set -e is ignored.

   set -e
   foo() { echo a; false; echo b; }
   trap -- "echo INT; foo" INT
  
   sleep 100 || :

$ bash t.sh
^CINT
a
$ dash t.sh
^CINT
a
$
Desired Action Clarify, whether or not any ignoring of set -e would propagate to any trap actions or whether this is unspecified.

If it does NOT propagate, one could e.g.:
APPEND on page 2554 after line 83319 or after 83308:

   If any trap action is executed from a context in
   which set -e is ignored, the effects of that do
   not propagate into the trap action.

If it's unspecified, then at the same position:
   If any trap action is executed from a context in
   which set -e is ignored, it is unspecified whether
   or not the effects of that do propagate into the
   trap action.

Thanks,
Chris.
Tags No tags attached.
Attached Files

- Relationships

-  Notes
(0006962)
geoffclare (manager)
2024-11-19 10:45

I think what's been missed here is a subtlety in this quoted text:

> When a signal for which a trap has been set is
> received while the shell is waiting for the completion
> of a utility executing a foreground command, the trap
> associated with that signal shall not be executed until
> after the foreground command has completed.

Note it says "after the foreground command has completed", i.e. the whole command has completed, not just the utility that the shell was waiting for.

In the tested script, the foreground command is "sleep 100 || :". The sleep is terminated by the SIGINT and the shell then completes execution of the foreground command by evaluating the || condition and executing the ":" (because the sleep did not succeed). Only then does it execute the trap action, at which point the AND-OR list exception for set -e no longer applies. So the standard requires the behaviour exhibited by bash and dash in the test.

The phrase "a utility executing a foreground command" is a little odd, as strictly speaking the shell is the only utility which can execute a foreground command. It should be changed to something like "a utility executing as part (or all) of a foreground command".
(0006964)
calestyo (reporter)
2024-11-19 15:42

Well it doesn't specifically say that it's about the *whole* command, and even if, the term "whole command" would also be a bit ambiguous.

Is a simple command by itself a whole command, when e.g. part of a list, function, etc.?

Also, 2.9 Shell Commands says:
>A command is one of the following:
> Simple command (see 2.9.1 Simple Commands )
> Pipeline (see 2.9.2 Pipelines )
> List compound-list (see 2.9.3 Lists )
> Compound command (see 2.9.4 Compound Commands )
> Function definition (see 2.9.5 Function Definition Command )

2.9.3 Lists in turn says:
> The term "compound-list" is derived from the grammar
> in 2.10 Shell Grammar ; it is equivalent to a sequence
> of lists, separated by <newline> characters, that can
> be preceded or followed by an arbitrary number of
> <newline> characters.

Wouldn't that mean that something like:

sleep 100 || :
sleep 50

is also, both together, a command (two lists separate by newline)?
But I'd guess the intention is that the trap action is executed after the : but before the sleep 50, right?


Also, are you sure the : is still executed?
Change the example to:
  set -e
  foo() { echo a; false; echo b; }
  trap -- "echo INT; foo" INT
  
  sleep 100 || printf end

and neither dash nor bash print end after Ctrl-C.
(0006965)
oguzismailuysal (reporter)
2024-11-19 16:13

> Is a simple command by itself a whole command, when e.g. part of a list, function, etc.?

The `complete_command' production in XCU 2.10 Shell Grammar describes a "whole command".

> and neither dash nor bash print end after Ctrl-C.

Bash 5.2.37 does print `end' here.
(0006966)
geoffclare (manager)
2024-11-19 16:14
edited on: 2024-11-19 16:19

> Well it doesn't specifically say that it's about the *whole* command

2.11 Job Control says:
For a list consisting of one or more sequentially executed AND-OR lists followed by at most one asynchronous AND-OR list, the whole list shall form a single foreground job up until the sequentially executed AND-OR lists have all completed execution, at which point the asynchronous AND-OR list (if any) shall form a background job as described above.

Admittedly that's "foreground job" not "foreground command" (which isn't a defined term), and job control isn't enabled in the test script, but if the behaviour changed with job control enabled, that would be very surprising.

> neither dash nor bash print end after Ctrl-C.

That looks like a bug (or at least a non-conformance) in dash and bash. Ksh (all versions - 88, old 93, 93u+m) does print "end". However, it also prints "b" (meaning set -e is suppressed) so doesn't conform to my interpretation of the requirements for set -e.

Looks like this is one to raise with the various shell authors/maintainers to get their input.

(0006969)
calestyo (reporter)
2024-11-23 03:32

> Bash 5.2.37 does print `end' here.

My version of bash is 5.2.32, but the commits to .37 don't sound like anything related.

But I presume you ran the function/command interactively (where I also get `end` printed), not non-interactively?

- Issue History
Date Modified Username Field Change
2024-11-18 23:54 calestyo New Issue
2024-11-18 23:54 calestyo Name => Christoph Anton Mitterer
2024-11-18 23:54 calestyo Section => 2.15 Special Built-In Utilities
2024-11-18 23:54 calestyo Page Number => 2554
2024-11-18 23:54 calestyo Line Number => 83295, ff.
2024-11-19 10:45 geoffclare Note Added: 0006962
2024-11-19 15:42 calestyo Note Added: 0006964
2024-11-19 16:13 oguzismailuysal Note Added: 0006965
2024-11-19 16:14 geoffclare Note Added: 0006966
2024-11-19 16:19 geoffclare Note Edited: 0006966
2024-11-23 03:32 calestyo Note Added: 0006969


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker