[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: user/421: ksh: "command | read" produces null/unset variables
- To: bugs_(_at_)_cvs_(_dot_)_openbsd_(_dot_)_org
- Subject: Re: user/421: ksh: "command | read" produces null/unset variables
- From: Otto Moerbeek <otto_(_at_)_drijf_(_dot_)_net>
- Date: Tue, 10 Jun 2003 09:15:02 -0600 (MDT)
- Cc:
- Reply-to: Otto Moerbeek <otto_(_at_)_drijf_(_dot_)_net>
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