Quick question to Linux G'MIC users.

No surprises. Shells are PITAs.

Tutorial Land suggests that G’MIC students should get out of dueling interpreter environments as soon as possible. Such can’t be entirely avoided — the shell running in the controlling terminal has to launch G’MIC and pass on the remainder of the command line.

But shells may have their own schemes afoot — a variable substitution enterprise apart from G’MIC’s, perhaps — so the remainder of command line may or may not be exactly what was first typed. That is the dueling interpreter problem. And, as @afre points out, there are a lot of shells in play among Linux users, and shells all have their command line processing eccentricities. One can even switch shells on the fly, as I did in Post #7 in going from bash to sh.

So Example #4, (debug dumped), typed in a controlling terminal running GNU’s Bourne Again SHell, version 5.2:

$ gmic debug m=$\{rep_cin\ \{\'\"Test A: \"\'\}\} echo $m

yields a debugging report that, in part, shows what gets finally delivered to G’MIC and how the G’MIC interpreter processes it:

<gmic>./ Item[3]: 'm=\$\{rep_cin \{'Test A: '}}', selection [].
[gmic]./ Set local variable 'm=${rep_cin {'Test A: '}}'.

Setting a local variable m wasn’t anyone’s intent, but that’s how G’MIC played it, given the (Bourne shell) pre-processed command line. Of course, what example #4 seems to be striving for is a syncopated form of G’MIC’s pipeline substitution rule.

G’MIC has two Substitution Rules with very nearly identical templates:

  1. {"-<pipeline>"}<status>
  2. {"<key>"}<value>

The hyphen (-) in the first template is all what distinguishes it from the second template. Enchantingly, and for practial purposes, that hyphen is optional. Suppose that we omit it. The G’MIC interpreter then takes the construction to be the keyvalue form.

Well now. What if <key> doesn’t look like a proper variable? Maybe <key> has space characters within and looks (suspiciously) like a pipeline. In that case, the G’MIC interpreter then tries the first template form and run <key> as if it is a pipeline. Yes, the hyphen is not present, but if <key> looks like a pipeline, then G’MIC plays it as a pipeline. Convenient.

Alas, with Example #4, the parse never makes it so far as trying one substitution template or another. Following Bourne Shell’s pre-emptive processing, the G’MIC interpreter observes, first and foremost, a = assignment. m is on the left hand side. ${rep_cin {'Test A: '}} is on the right. G’MIC sees a command line variable definition, makes the assignment and moves on. Another shell might deliver G’MIC a somewhat differently pre-processed command line and a different result could prevail.

Another illustration of the Bourne shell’s pre-emptive processing behavior can be seen with the G’MIC command sequence echo $m — an escape for the $ character was inadvertently omitted. The debugger reports:

<gmic>./ Item[4]: 'echo', selection [].
<gmic>./ Command 'echo': arguments = ''.

<gmic>./ Exit scope './'.

When the Bourne Shell finally delivers the command line to the G’MIC interpreter, $m is nowhere to be found. That is because the Bourne Shell is doing its own substitution scheme and took $m for one of its own. In this case, there was no defined value for the key m, so the Bourne Shell inserted the default empty string value instead. Downstream, G’MIC finds that echo has no arguments, so echo dispatches to its default, no-argument, behavior of just producing a new line.

That’s how life plays out with Bourne Again SHell, version 5.2. As noted, another shell might deliver a somewhat different string to the G’MIC interpreter and different behavior might ensue. @Reptorian sees the substitution play out as he expects in Windows PowerShell, but the Bourne Again SHell has different rules.

And then there are all the other shells. Test all of them? Such gives rise to chilblains, and Tutorial Land’s practical, if not courageous, scheme to get out of dueling interpreter environments as soon as it can. Shells can’t be entirely avoided — something has to start the G’MIC interpreter — but, beyond that, the scheme is to give the controlling terminal’s shell interpreter as little as possible to do.

Perhaps just:

$ gmic m examplefour.txt examplefour

examplefour.txt is a command file with the wrong extension to get past the File Police here. G’MIC’s command happens to be agnostic about file extensions so long as the file contents parses out correctly. examplefour.txt defines two custom commands. One is new_rep_cin which is just a cut-and-paste of what @Reptorian provided above. The other is examplefour:

examplefour: 
   m=${"new_rep_cin \"Test A: \""}
   echo $m

examplefour is a hook that can be cited on the controlling terminal’s command line without triggering unexpected behavior. There is little that this ‘outer’ interpreter has to interpret, so there is little that it can screw up. m exampefour.txt examplefour, having no special characters, passes to the G’MIC interpreter unchanged.

examplefour.txt (3.5 KB)

More importantly, the custom command examplefour is parsed only by G’MIC. One need not worry about the characteristics of who knows how many shells; its a closed interpretation problem, and the behavior of the G’MIC interpreter is well understood. Only a bit of escaping is needed so that a string with embedded spaces can passed to new_rep_cin.

The debug dump file goes into the gory details of command interpretation.
examplefour_debug.txt (158.2 KB)

Indeed. Trying to enter BINGO!

It seems to me that the real tricky bit is coding what amounts to a basic shell interpreter for a G’MIC interactive window. What works for waits on your hardware might not work on mine or someone else’s ten year old Dell laptop.

At least you won’t be bored.

1 Like