Bug 44142

Summary: /bin/sh does not support 'command1 & && command2' syntax, which is REQUIRED by POSIX
Product: Base System Reporter: never
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.7-RELEASE   
Hardware: Any   
OS: Any   

Description never 2002-10-16 15:20:01 UTC
/bin/sh does not support 'command1 & && command2' syntax, which is REQUIRED by POSIX:
According to:
http://www.opengroup.org/onlinepubs/007904975/utilities/xcu_chap02.html#tag_02
(which is part of SUSv3 specification):

1. Shell command definition
--- cut ---
Shell Commands

This section describes the basic structure of shell commands. The following
command descriptions each describe a format of the command that is only used to
aid the reader in recognizing the command type, and does not formally represent
the syntax. Each description discusses the semantics of the command; for a
formal definition of the command language, consult Shell Grammar .

A command is one of the following:
	Simple command (see Simple Commands )
	Pipeline (see Pipelines )
	List compound-list (see Lists )
	Compound command (see Compound Commands )
	Function definition (see Function Definition Command )
--- cut ---

2. Asynchronous list definition
--- cut ---
Asynchronous Lists

If a command is terminated by the control operator ampersand ( '&' ), the shell
shall execute the command asynchronously in a subshell. This means that the
shell shall not wait for the command to finish before executing the next
command.

The format for running a command in the background is:

command1 & [command2 & ... ]

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. If it is an interactive shell, this need not happen.
In all cases, explicit redirection of standard input shall override this
activity.

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:

   1. The command terminates and the application waits for the process ID.
   2. Another asynchronous list invoked before "$!" (corresponding to the
	  previous asynchronous list) is expanded in the current execution
      environment.

The implementation need not retain more than the {CHILD_MAX} most recent
entries in its list of known process IDs in the current shell execution
environment.

Exit Status

The exit status of an asynchronous list shall be zero.
--- cut ---

3. AND list definition
--- cut ---
AND Lists

The control operator "&&" denotes an AND list. The format shall be:

command1 [ && command2] ...

First command1 shall be executed. If its exit status is zero, command2 shall be
executed, and so on, until a command has a non-zero exit status or there are no
more commands left to execute. The commands are expanded only if they are
executed.

Exit Status

The exit status of an AND list shall be the exit status of the last command
that is executed in the list.
--- cut ---

Using those definitions:

	a) 'command1 &', which is correct asynchronous list is command;
	b) 'command2', which is simple command is command;
	c) let 'command1 &' will be 'k1', look at a) for 'why?';
	d) let 'command2' will be 'k2', look at command definition for 'why?';
	e) 'k1 && k2' is command according to command definition and will be
       correct AND list;
	f) as far as 'k1 && k2' is correct (and REQUIRED to support) construct by
	   SUSv3, and 'k1' == 'command1 &' and 'k2' == 'command2', 'command1 & &&
       command2' is correct (and REQUIRED to support) syntax according to SUSv3.

Resume: we need to backout changes to /bin/sh, which prevents 'command1 & &&
command2' from being evaluated correctly.

Fix: 

Backout relevant changes.
How-To-Repeat: Try to run 'ls & && ls' on 4.7-RELEASE and -STABLE.
Comment 1 wollman 2002-10-16 16:55:42 UTC
<<On Wed, 16 Oct 2002 17:16:54 +0300 (EEST), Alexandr Kovalenko <never@nevermind.kiev.ua> said:

> /bin/sh does not support 'command1 & && command2' syntax, which is REQUIRED by POSIX:

Your interpretation is erroneous.  The grammar takes precedence over
the textual description of the syntax, and the grammar is quite clear:

complete_command	: list separator
			| list
			;
list			: list separator_op and_or
			|		    and_or
			;
and_or			:			    pipeline
			| and_or AND_IF   linebreak pipeline
			| and_or OR_IF    linebreak pipeline
			;

The pseudo-syntax `command1 &' can only be resolved by the `list'
production in the grammar.   The `&&' and `||' operators take
pipelines, and not lists, as operands.  See XCU6 page 58.

-GAWollman
Comment 2 Garrett Wollman freebsd_committer freebsd_triage 2002-10-16 16:55:59 UTC
State Changed
From-To: open->closed

The Standard is quite clear and does not support submitter's desired 
interpretation of the shell grammar.
Comment 3 never 2002-10-16 17:26:12 UTC
Hello, Garrett Wollman!

On Wed, Oct 16, 2002 at 11:55:42AM -0400, you wrote:

> > /bin/sh does not support 'command1 & && command2' syntax, which is REQUIRED by POSIX:
> 
> Your interpretation is erroneous.  The grammar takes precedence over
> the textual description of the syntax, and the grammar is quite clear:
> 
> complete_command	: list separator
> 			| list
> 			;
> list			: list separator_op and_or
> 			|		    and_or
> 			;
> and_or			:			    pipeline
> 			| and_or AND_IF   linebreak pipeline
> 			| and_or OR_IF    linebreak pipeline
> 			;
As we can see from Grammar:

pipeline         :      pipe_sequence
                 | Bang pipe_sequence
                 ;
pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command
                 ;
So, we can parse 'command1 & && command2' in this way:

'command1 & && command2' : and_or(complete_command(list('command1') separator(' ')) separator_op('&') AND_IF pipeline('command2'))

> The pseudo-syntax `command1 &' can only be resolved by the `list'
> production in the grammar.   The `&&' and `||' operators take
> pipelines, and not lists, as operands.  See XCU6 page 58.
Yes. It is correct. Sorry for false alert.

-- 
NEVE-RIPE
Ukrainian FreeBSD User Group
http://uafug.org.ua/