Digressing a bit (but only a bit) talking about IPC: Powershell and CMS PIPELINES both take the approach of more structured pipelines, where pipe contents are not just streams of bytes but can be structured records.  This offers a lot of power, but it also inhibits the ability to arbitrarily compose pipe stages, because you've effectively introduced a type system.

On the other hand you can certainly argue that stream-of-bytes pipes ALSO introduce a type system, it's just a completely ad-hoc, undocumented, and fragile one that relies on the cooperation of both ends of the pipe to work at all, and you'd be right.

In practice...well, I'd rather use stream-of-bytes, but I am more comfortable in Unix-like environments than Powershell, and my CMS PIPELINES skills are quite rusty now.

On Sat, Jul 31, 2021 at 7:21 AM Adam Thornton <athornton@gmail.com> wrote:


On Jul 31, 2021, at 5:25 AM, Michael Siegel <msi@malbolge.net> wrote:

While doing that, I learned that there is a better way to approach
this problem – beyond using getopt(s) (which never really made sense to
me) and having to write case statements in loops every time: Define a
grammar, let a pre-built parser do the work, and have the parser
provide the results to the program.

I see that Dan Halbert beat me to mentioning "click."

The trick with shell is that unless you write the parser in shell, which is going to be miserable, you’re doing it in a command in a subshell, and therefore your return values have to be a structured stream of bytes on stdout, which the parent shell is going to have to interpret.  An eval-able shell fragment, where you have a convention of what the variables you get from the option parser will be, is probably the easiest way, since from the parent that would look like:

$(parse_my_opts $*)
# Magic variables spring to life
if [ “$OPT_SUBCOMMAND_0” == “burninate” ]; then ….

Adam