Austin Group Defect Tracker

Aardvark Mark III

Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001254 [1003.1(2016)/Issue7+TC2] Shell and Utilities Objection Error 2019-06-08 09:14 2019-06-10 18:34
Reporter stephane View Status public  
Assigned To
Priority normal Resolution Open  
Status New  
Name Stephane Chazelas
User Reference
Section Asynchronous Lists
Page Number 2370 (in 2018 edition, not 2016)
Line Number the whole section and also 76177 (execution environment), 115763 (wait), 128448 (rationale), 74883 ($!)
Interp Status ---
Final Accepted Text
Summary 0001254: "asynchronous list" description uses "command" instead of "AND-OR list"
Description That's a follow-up on my Note: 0004410 comment on 0000760.

2.9.3 correctly specifies that "an '&' separator or terminator shall cause asynchronous execution of the preceding AND-OR list."

In POSIX shells, rc-like shells and csh-like shells, zsh being the only exception that I know,

a && b || c &

is interpreted as:

{ a && b || c; } &


a && b || { c & }

But then only talks about "commands" started asynchronously, not even pipelines let alone AND-OR lists.

The sentence: "When an element of an asynchronous list (the portion of the list ended by an <ampersand>, such as command1, above) is started by the shell, the process ID of the last command in the asynchronous list element shall become known in the current shell execution environment; see Shell Execution Environment. This process ID shall remain known until:..." doesn't make sense.

Without giving a proper definition of "asynchronous list", it suggests that in:

  false && cmd2 &

The pid of cmd2 (what's the pid of a command btw?) should somehow become known (as $! presumably) whenever cmd2 is started (if ever it's started which is unlikely in that example). What should $! be until then?

The wait utility description has similar wording, worse in that it suggests $! should be updated for every command run in the list.

I suspect at some point "asynchronous list" must have been (confusingly) defined in the grammar as a sequence of 1 more of "and-or-list &" which would explain. There's a clue about that in the rationale at line 128448:

   The grammar treats a construct such as:

     foo & bar & bam &

   as one "asynchronous list", but since the status of each element is tracked by the shell, the term "element of an asynchronous list" was introduced to identify just one of the foo, bar, or bam portions of the overall list.

So the "component of an asynchronous list" in probably does not refer to the pipeline component of the asynchronously started AND-OR list, but to one AND-OR list component of a "and-or-list1 & and-or-list2 & and-or-list3 &".

AFAICT, in the current version of the spec, asynchronous_list is not defined in the grammar (it wasn't in SUSv2 either). "and_or" is.

Which process we get in $! is important as we want to know what the effect of killing that process will be and it's important that calling "wait" on that pid should give us the exit status of the AND-OR-list.
Desired Action - Clearly define what is meant by an asynchronous list. The definition suggested by the rationale (cmd1 && cmd2 & cmd3 || cmd4 & being *one* asynchronous list) but AFAICT absent from the current specification is confusing.

I'd rather it be one single "AND-OR list" run asynchronously with & as there's no reason to treat "list1 & list2 & list3 & list4" (with the exclusion of list4) as part of a single construct. If that definition is chosen, the text in the wait utility and the rationale at least would have to be updated.

Calling it an "asynchronous *AND-OR* list" might even remove even more confusion .

- Update, and $!/wait/execution environment description to remove the reference to "command" and replace with "AND-OR list"

- Clarify that the pid stored in $! should be the id of a child process that runs a subshell to execute that and_or list, make it clear that that process will exit with the exit status of the and_or list, and that if the and_or list consists of a single pipeline, the last component of the pipe line will be executed by that pid (sleep 1 | sleep 2 & sleep 1; kill "$!" should stop the execution of "sleep 2", same for sleep 2 & sleep 1; kill "$!")
Tags No tags attached.
Attached Files

- Relationships

-  Notes
stephane (reporter)
2019-06-10 18:34

I think that it makes sense to address the other objections I raised in Note: 0004410 and Note: 0004411 of 0000760 in this same bug.

the new bug760 wording of:

> If job control is disabled (see set, −m), the standard input for
> an asynchronous list, before any explicit redirections are
> performed, shall be considered to be assigned to a file that has
> the same properties as /dev/null. This shall not happen if job
> control is enabled. In all cases, explicit redirection of
> standard input shall override this activity.

seems to assume "my" definition of "asynchronous list" as it doesn't make sense to speak of "the standard input for an asynchronous list" when that asynchronous list can be "cmd1 & cmd2 &". If "redirection of standard input shall override this activity", that would imply in

   cmd1 < foo & cmd2 &

cmd2's stdin would not be redirected to /dev/null.

IMO, after "asynchronous list" has been clearly defined as "AND-OR-list followed by &", and maybe renamed to "asynchronous AND-OR list", that whole paragraph should be changed to something like:

} If job control is disabled (see set, −m), an implementation may
} choose to assign the standard input of an asynchronous AND-OR
} list to an open file description that behaves as if /dev/null
} had been opened in read-only.
} This shall not happen if job control is enabled.
} Where and if that happens, that shall happen before any explicit
} redirection of any command in the asynchronous AND-OR list is
} processed.
} A portable application that needs to make sure that is done
} would need to make the /dev/null redirection explicitly:
} < /dev/null cmd1 | cmd2 && < /dev/null cmd3 &
} Or
} { cmd1 | cmd2 && cmd3 ; } < /dev/null &
} A portable application that needs to make sure it is not done
} would need to duplicate the original stdin outside of the
} asynchronous AND-OR list and restore it inside for instance as:
} { <&3 3<&- cmd1 | 3<&- cmd2 && <&3 3<&- cmd3 & } <&3
} Or:
} { { cmd1 | cmd2 && cmd3 ; } <&3 3<&- & }
} As whether it is done or not in:
} cmd1 | cmd2 && cmd3 &
} Is unspecified.

- Issue History
Date Modified Username Field Change
2019-06-08 09:14 stephane New Issue
2019-06-08 09:14 stephane Name => Stephane Chazelas
2019-06-08 09:14 stephane Section => Asynchronous Lists
2019-06-08 09:14 stephane Page Number => 2370 (in 2018 edition, not 2016)
2019-06-08 09:14 stephane Line Number => the whole section and also 76177 (execution environment), 115763 (wait), 128448 (rationale), 74883 ($!)
2019-06-10 18:34 stephane Note Added: 0004416

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