What I see so far from this discussion: Ted has written a lot of useful scripts, but they are explicitly for one shell (bash) on one kernel (linux). I.e. portability is not a concern.

People immediately pointed out how easy it is to write non-portable shell scripts, and others commented that it does not matter (to them).

Kernel portability matters to me. So does code that works without regard to the shell someone is using. So does robust error handling. So does math. These are all things that, in my experience, rule against complex shell scripts. 

I still prefer Go as my scripting language, but we all have our preferences. And, yes, Go gets wordy, but it's a price I'm happy to pay for good error handling. I much prefer an error message to 100 lines of python backtrace.

On Wed, Jan 4, 2023 at 8:17 AM Dan Cross <crossd@gmail.com> wrote:
On Tue, Jan 3, 2023 at 11:16 PM Bakul Shah <bakul@iitbombay.org> wrote:
> On Jan 3, 2023, at 7:31 PM, Dan Cross <crossd@gmail.com> wrote:
> > On Tue, Jan 3, 2023 at 10:22 PM John Cowan <cowan@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.