[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: user/421: ksh: "command | read" produces null/unset variables



The following reply was made to PR user/421; it has been noted by GNATS.

From: Otto Moerbeek <otto_(_at_)_drijf_(_dot_)_net>
To: bugs_(_at_)_openbsd_(_dot_)_org
Cc:  
Subject: Re: user/421: ksh: "command | read" produces null/unset variables 
Date: Sat, 24 May 2003 12:10:56 +0200

 Hi,
 
 Some time ago I posted the message below to bugs_(_at_)__(_dot_)_ No discussion  
 followed. I'm attaching the message to the PR anyway, since it contains  
 a lot of relevant references.
 
 	-Otto
 
 ==================================
 Hi,
 
 PR 412  
 <http://cvs.openbsd.org/cgi-bin/query-pr-wrapper?full=yes&numbers=421>  
 describes the following problem:
 
 $ echo 1 2 | read a b
 $ echo $a $b
 
 Should print
 1 2
 
 But as the manual page states, this does not happen with the pd version  
 of ksh.
 
 I tried various incarnations of the bourne shell, korn shell and bash  
 on various OSes and all have the same behavior: the last command is  
 executed in a subshell.
 
 Digging deeper, I found out that the original (AT&T) ksh has changed  
 with respect to this. Versions prior to the 1988 ksh did execute the  
 last command of a pipe in a subshell. Versions from 1988 and newer do  
 execute the last command in the current environment.
 
 See <http://www.kornshell.com/doc/faq.html>, Q13 and M.i. Bolsky and  
 D.G. Korn, The Kornshell Command and Programming Language, 1989, page  
 190.
 
 Today, a lot of systems (like OpenBSD) use the pd version of ksh, which  
 cleary states it uses a subshell for the last command in a pipe:  
 <http://web.cs.mun.ca/~michael/pdksh/NOTES> and the manual page.
 
 I do not know how the original SysV sh handles this, but I the Open  
 Group Single Unix Specifications version 2  
 <http://www.opengroup.org/onlinepubs/007908799/xcu/ 
 chap2.html#tag_001_012> specifies that:
 
 "Some systems have implemented the last stage of a pipeline in the  
 current environment so that commands such as:
 
 command | read foo
 
 set variable foo in the current environment. This extension is allowed,  
 but not required; therefore, a shell programmer should consider a  
 pipeline to be in a subshell environment, but not depend on it."
 
 Version 3 of the Single Unix Specifications
 <http://www.opengroup.org/onlinepubs/007904975/utilities/ 
 xcu_chap02.html#tag_02_12> says in the corresponding section:
 
 "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."
 
 Although the OpenBSD ksh handles pipes differently from more recent  
 versions of the original (AT&T) ksh, I think it makes sense to classify  
 this PR as "not a bug", since the current behavior is allowed by Single  
 Unix and programmers are discouraged to rely on the specific subprocess  
 related behavior of pipes. Furthermore, the current behavior is clearly  
 documented in the man page.
 
 	-Otto



Visit your host, monkey.org