I apologize for this too long message, but context in this case matters. 

tl;dr: I agree with the Go folks: past about 10 lines, write a program. But not everybody will agree, as I learned with u-root. Many people love shell programming. I never have.

u-root is a set of Go programs deployed on a couple million data center systems at many companies, including Google.

u-root originally used a compile-on-demand model: type a command name, if it's not in /ubin, it gets built. This was fast, in early Go, typically 250 ms or so. And, in the early days of Go, the Go toolchain, u-root, and all support source easily fit in a 16M SPI part.

The original scripting language for u-root was Go. 

There were two commands for this: script and builtin. script would run Go fragments; builtin would take supplied commands and build a custom shell with those built in. Each took 250ms to run.

script took what we called a 'Go fragment', wrapped it with boiler plate, compiled it, and ran it. 
e.g.
script fmt.Printf("hi\n")
would build the program and run that code. 
So you could, e.g,, do math:
script fmt.Printf("%d\n", 6*7)

It could get complex: to see things about interfaces:
script 'ifaces, _ := net.Interfaces()
for _, v := range ifaces {
addrs, _ := v.Addrs()
Printf("%v has %v", v, addrs)
}'

you'd get:
ip: {1 1500 lo  up|loopback} has [127.0.0.1/8 ::1/128]
ip: {5 1500 eth0 fa:42:2c:d4:0e:01 up|broadcast} has [172.17.0.2/16 fe80::f842:2cff:fed4:e01/64]

The second command was called builtin. It did not work as other shells do: it built a new shell for you. So, you type:
bulitin hi fmt.Printf("hi") there fmt.Printf("there\n")

builtin would convert the Go fragments to functions callable in the u-root shell, build a private name space (on Linux or Plan 9 anyway), rebuild the shell with those new functions, and at that point:
you type
hi
in the shell, and it types
hi
back. This was built in to your private shell in your private name space. Once you left the shell, it was gone.
Again, this process of creating and starting the new shell always took about 250 ms (in Go 1.2 that is).

I learned a lesson: people love their shell scripting languages. Nobody wanted to script with Go. It made me sad, but that's how it Go-es.

ron
p.s. the 'script' command is still available as an experimental u-root command. Source mode is now independent: github.com/u-root/sourcery


On Tue, Jan 3, 2023 at 2:35 PM Steffen Nurpmeso <steffen@sdaoden.eu> wrote:
Steve Nickolas wrote in
 <alpine.DEB.2.21.2301031307001.9988@sd-119843.dedibox.fr>:
 |On Tue, 3 Jan 2023, Dan Cross wrote:
 |> Something I've noticed is that lots of people try to increase
 |> complexity to solve problems, and it rarely occurs to them to
 |> eliminate complexity to solve problems. Sometimes the reasons for this
 |> are good; most of the time they are not.
 |>
 |>        - Dan C.
 |
 |I think of the saying: "Perfection is not when there is nothing left to
 |add, but when there is nothing left to remove."

He (Exupéry) was then shot down.

I always seem to response this to that.
Hmm, openpgp@ietf.org (to which i have almost zero to add
technically shall someone think that, nor do i want) lastly

   |"Perfection is achieved not when there is nothing more to add but when \
   |there
   |is nothing left to take away" - Antoine de Saint-Exupéry.

  He was then shot down.

But yes, he then really went missing.

The topic ..
I do not miss times where suddenly a shell script breaks because
": > FILE" does not work (just recently 'realized from reading code
of Paul Eggert of GNU/IANA TZ, "hey, > FILE" is of course
sufficient!"), i fixed it via "printf '' > FILE" by then; whatever
the reason.  May it be bugs or (local) miscompilations, not
detected due to missing unit tests and a too small user base.

Portable?  If i find /usr/xpg4/bin i quickly add it to $PATH for
the much better awk (but beware of documented double expansion
issues) and the much much better sh(1).
Some things just require that, noclobber I/O redirection (set -C)
for example.  (mktemp(1) is still not part of the POSIX standard.)

Besides i miss(ed) the history; the author of bmake (and
verieexec) just last year asked me why i would use stty for
a purpose ("(<&1 >/dev/null stty -a) 2>/dev/null") instead of
simply using "[ -t 1 ]", and indeed, i found that as soon as BSD
4.1 and Research V7, but it surprised me.
Without an oversight of the history and the lack of many systems
to test, perl(1) was omnipresent and if only for OpenSSL and so
using it for almost anything seemed save.

  To love is not to look at one another: it is to look,
  together, in the same direction.  Antoine de Saint-Exupéry.

A happy and healthy new Year 2023 is now overdue.
Even Giants have to die, but with holding hands it can wait a bit
longer, i hope.
I wish that from Germany to all of you, and deliberately beyond
NATO readership.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)