[TUHS] A few comments on porting the Bourne shell

Dan Cross crossd at gmail.com
Thu Jan 5 02:15:17 AEST 2023


On Tue, Jan 3, 2023 at 11:16 PM Bakul Shah <bakul at iitbombay.org> wrote:
> On Jan 3, 2023, at 7:31 PM, Dan Cross <crossd at gmail.com> wrote:
> > On Tue, Jan 3, 2023 at 10:22 PM John Cowan <cowan at ccil.org> wrote:
> >> Making shell scripts portable means not using pipelines, because given "foo | bar", kshNN and zsh execute foo in a subshell and bar in the top-level shell, whereas in other shells, both foo and bar execute in subshells.  (For this reason, Posix allows either behavior.)  Not having pipelines is a pretty drastic limitation.
> >
> > This came up at work just the other day:
> >
> > echo ' hi ' | sed 's/^ *//;s/ *$//' | read bummer
> > echo $bummer
> >
> > The behavior varies between ksh, zsh, bash, sh. Yay.
>
> On this example sh, zsh, bash behave the same way on
> freebsd. Rather than ban |, I think the lesson is to
> *avoid* builtin commands in a pipeline that can affect
> shell's environment. I only write /bin/sh scripts in
> any case.

Interesting. In my testing, `bash` was the odd man out:

: doctor; zsh
: doctor; echo ' hi ' | sed 's/^ *//;s/ *$//' | read bummer
echo $bummer

hi
: doctor;
: doctor; bash
: doctor; echo ' hi ' | sed 's/^ *//;s/ *$//' | read bummer
echo $bummer

: doctor;
exit
: doctor; ksh
: doctor; echo ' hi ' | sed 's/^ *//;s/ *$//' | read bummer
: doctor; echo $bummer
hi
: doctor;
: doctor; sh
: doctor; echo ' hi ' | sed 's/^ *//;s/ *$//' | read bummer
: doctor; echo $bummer
hi
: doctor;
: doctor;

That's on illumos.

On OpenBSD, neither bash, ksh, or sh produce output, while zsh does. I
suspect ksh is pdksh and sh is a link to ksh there, though. ksh93
gives "hi".

On FreeBSD, neither bash nor sh produce "hi", but zsh and ksh93 do.
Same on DragonFly, macOS and Arch Linux. On 7th edition, I only tried
sh; empty output. 4.3BSD gives empty output for /bin/sh. For kicks,
neither tcsh nor csh understand `read`; I don't think that *csh has a
read-like builtin.

This is, of course, a silly example. Most script authors would do
something like:

    bummer=`echo ' hi ' | sed 's/^ *//;s/ *$//'`

Or, perhaps even:

    bummer=$(echo ' hi ' | sed 's/^ *//;s/ *$//')

Life's too short and at this point I prefer the latter, but more often
than not my fingers are wired for the former.

> It is really unfortunate that infix | is so beguiling!
> Except for that a Lisp or Scheme based shell would've
> been fine and dandy! :-)/2

Whatever happened to `es` ? I guess it died on the vine. It seemed
like a nifty idea.

I made a concerted effort to use `rc` as my shell on Unix for a little
while. Without all the supporting plan9 machinery, though, I gave up.
Minimalism is great in an environment that can augment it with useful
functionality; outside of that environment, it can be kind of a pain
for work-a-day use.

        - Dan C.


More information about the TUHS mailing list