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
0001042 [1003.1(2013)/Issue7+TC1] Shell and Utilities Objection Clarification Requested 2016-04-03 11:16 2017-03-23 16:09
Reporter dannyniu View Status public  
Assigned To
Priority normal Resolution Rejected  
Status Closed  
Name DannyNiu/NJF
Organization
User Reference
Section XCU 2.14 break, continue, exit, return
Page Number 2374 2379 2387 2395
Line Number 75994 76154 76419 76664
Interp Status ---
Final Accepted Text
Summary 0001042: Behavior of break, continue, exit and return are undefined if invoked from a multi-stage pipeline.
Description Recently I've been playing around coding. I tried to create a multi-text-processing program by segmenting inputs using the head(1) command.

Let's first put aside if it was sane to do that and focus on this: I used a construct similar to this:

while true
do
    cat | tee | { read -r var ; [ "$var" = 123 ] && echo yes && break ; }
done

I created a script with these commands, and invoked it and typed 123 into my terminal. What I get is just yes, I didn't get another command prompt. The loop didn't break.

I experimented further and confirmed that even if the break is at the first stage, it still doesn't work, nor does exit when invoked as such.
Desired Action Add to the DESCRIPTION sections of break, continue, exit, and return:

The behavior is undefined if break|continue|exit|return was invoked from a multi-stage pipeline.
Tags No tags attached.
Attached Files

- Relationships

-  Notes
(0003119)
dannyniu (reporter)
2016-04-04 01:47

Nearly forgot, assignment command doesn't work either in multi-stage pipeline.

Add to section 2.5.3 Shell Variables of XCU:

The behavior is undefined if assignment command occurs inside a multi-stage pipeline.
(0003120)
Don Cragun (manager)
2016-04-04 02:26
edited on: 2016-04-04 02:30

The last paragraph of XCU Section 2.12 Shell Execution Environment (P2354, L74999-75006) says:
A subshell environment shall be created as a duplicate of the shell environment, except that signal traps that are not being ignored shall be set to the default action. Changes made to the subshell environment shall not affect the shell environment. Command substitution, commands that are grouped with parentheses, and asynchronous lists shall be executed in a subshell environment. Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. All other commands shall be executed in the current shell environment.

I would think it would be obvious that a break in a subshell can't break out of a loop that is not in the same shell execution environment. Similarly, exit exits from the subhsell environment; not the parent shell and the results of using return when you are not in a shell execution environment running a function or a dot script is unspecified.

(0003130)
joerg (reporter)
2016-04-06 09:56
edited on: 2016-04-06 09:56

Correct:

In a pipeline, the historical implementation did run all commands
from that pipeline in a subshell. The historic implementation was
that the shell first creates a subshell and then lets all commands
for that pipeline become children of that subshell. This is not
the optimum for performance, but it is the easiest method to
implement.

Some shells that have been rewritten since then, may do things in
a different way, but in such a shell, a pipeline that ends in "read"
is still not guaranteed to run "read" in the main shell process.

ksh93 is one of the shells that uses the modern approach for creating
pipelines and that runs "read" in the main shell process. So ksh93
will exit the while loop in your case. Given that POSIX does not grant
the behavior you like to see for your script, you cannot rely on this
behavior.

(0003131)
shware_systems (reporter)
2016-04-06 16:52
edited on: 2016-04-07 00:23

Instead of:
while true
do
    cat | tee | { read -r var ; [ "$var" = 123 ] && echo yes && break ; }
done

doing:
while true
do
    cat | tee | { read -r var ; [ "$var" = 123 ] && echo yes } ;
if [ $? = 0 ] break;
done

gets the effect intended, as the pipeline result visible at the loop level should match the [ ] result.

As to exit and return, I think it's implicit that the value of $? is set appropriately from the result of the preceding command and execution continues after the last command the subshell is expected to process, skipping over any commands following. This is consistent with return and exit being used in function definitions, I believe, or usage in a script invoked as a simple command.

(0003132)
kre (reporter)
2016-04-07 00:10

I am not sure this is the right place to be holding a tutorial on sh behaviour,
but wrt note 3131 ...

    if [ $?=0 ] break;

    gets the effect intended,

I doubt it, as that is testing if "0=0" (or maybe "1=0) is the null string,
which it isn't, (test requires operators be separate args) so the break never
happens.

What would get the intended effect is ...

while true
do
    cat | tee | { read -r var ; [ "$var" = 123 ] && echo yes; } && break
done

(and where the "&& echo yes" is only useful if the objective is to have "yes"
appear on stdout when "123" is recognised).

I suspect this issue should be closed, there is nothing to change here.
(0003139)
shware_systems (reporter)
2016-04-07 19:41

I added it as a possible example for XCU 2.12 demonstrating the effect of the implied '(' ')' around pipeline commands the clause Don highlighted represents; that the first form does not affect the loop, but the second does. I edited in the spaces around '=' test requires, and use $? as a pipeline specific parameter with WEXIT_STATUS applied where ?? may reference an internal exit code variable wider than 8 bits directly and potentially produce false negatives. I expect additional edits if the consensus is an example like this should be added to get it to final form.
(0003649)
geoffclare (manager)
2017-03-23 16:09

This was discussed in the March 23, 2017 teleconference and the consensus was to reject based on Note: 0003120

- Issue History
Date Modified Username Field Change
2016-04-03 11:16 dannyniu New Issue
2016-04-03 11:16 dannyniu Name => DannyNiu/NJF
2016-04-03 11:16 dannyniu Section => XCU 2.14 break, continue, exit, return
2016-04-03 11:16 dannyniu Page Number => 2374 2379 2387 2395
2016-04-03 11:16 dannyniu Line Number => 75994 76154 76419 76664
2016-04-04 01:47 dannyniu Note Added: 0003119
2016-04-04 02:26 Don Cragun Note Added: 0003120
2016-04-04 02:27 Don Cragun Note Edited: 0003120
2016-04-04 02:27 Don Cragun Note Edited: 0003120
2016-04-04 02:27 Don Cragun Note Edited: 0003120
2016-04-04 02:28 Don Cragun Note Edited: 0003120
2016-04-04 02:29 Don Cragun Note Edited: 0003120
2016-04-04 02:29 Don Cragun Note Edited: 0003120
2016-04-04 02:30 Don Cragun Note Edited: 0003120
2016-04-06 09:56 joerg Note Added: 0003130
2016-04-06 09:56 joerg Note Edited: 0003130
2016-04-06 16:52 shware_systems Note Added: 0003131
2016-04-07 00:10 kre Note Added: 0003132
2016-04-07 00:23 shware_systems Note Edited: 0003131
2016-04-07 19:41 shware_systems Note Added: 0003139
2017-03-23 16:09 geoffclare Interp Status => ---
2017-03-23 16:09 geoffclare Note Added: 0003649
2017-03-23 16:09 geoffclare Status New => Closed
2017-03-23 16:09 geoffclare Resolution Open => Rejected


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