Subject: bin/16174: /bin/sh problem with grouped pipe and output redir
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mkb@mukappabeta.de>
List: netbsd-bugs
Date: 04/03/2002 00:26:59
>Number:         16174
>Category:       bin
>Synopsis:       /bin/sh problem with grouped pipe and output redir
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 02 14:28:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Matthias Buelow
>Release:        NetBSD 1.5.1
>Organization:
>Environment:

System: NetBSD moghedien.mukappabeta.net 1.5.1 NetBSD 1.5.1 (MOGGY) #0: Thu Jul 5 04:26:47 CEST 2001 mkb@moghedien.mukappabeta.net:/usr2/NetBSD/src/sys/arch/vax/compile/MOGGY vax


>Description:

	NetBSD's /bin/sh implementation's got a problem with regard
	to lists which contain pipes and I/O redirection that applies
	to the entire list.

	Please look at the following examples:

	First an ordinary grouped list with just one command:

	$ { :; }
	$ jobs
	$

	and with stdout/err redirected:

	$ { :; } >/dev/null 2>&1
	$ jobs
	$

	now with a pipe instead of a single command:

	$ { :|:; }
	$ jobs
	$

	so far everything ok as expected.  Now with redirection, it
	messes up:

	$  { :|:; } >/dev/null 2>&1
	$ jobs
	[1] 1473 Exit 2               :
	    1474 Exit 2               :
	$ 

	This should not happen; the shell should not print any background
	jobs (there must not be any, since the list is executed synchronously
	and not even in a subshell.)

	That wouldn't be so annoying if not, when used in the context of
	my .profile script (I use /bin/sh for root), it would cause premature
	end of parsing of said script, resulting in about half of the script
	not being run at all.  I've isolated a test example, which shows a
	sample premature abort of script parsing (when run in the context of
	the current shell at least, like it is done with sh reading .profile):


	cmdinpath()
	{
		{ type "$1"|grep '/'; } >/dev/null 2>&1
	}
	if cmdinpath less
	then PAGER=less
	else PAGER=more
	fi
	echo PAGER is $PAGER
	

	store into a file "t" and type the following:

	$ set -o xtrace		# doesn't change results, only shows
				# what the shell is doing
	$ . ./t
	+ . ./t
	+ cmdinpath less	# stops at "if cmdinpath less"...
	$ echo $?		# doesn't even get to the final echo
	+ echo 2
	2
	$ jobs
	[1] 1542 Exit 2               type ${1}
	    1543 Exit 2               grep /
	$

	For comparison, in Korn shell, the script executes properly:

	$ ksh93
	+ ksh93
	$ . ./t
	PAGER is less
	$ jobs
	$

	It also works as expected in the SystemV Bourne shell, ksh88
	and pdksh.  FreeBSD's (4.5) /bin/sh, which is also derived from
	the 4.4BSD-modified Almquist-sh has the same problem (already
	did a send-pr for that system before this report, see
	FreeBSD gnats bin/36671 entry.)
	

>How-To-Repeat:

	See above.

>Fix:

	None yet; I'll perhaps have a look into it.

>Release-Note:
>Audit-Trail:
>Unformatted: