help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sub-process changing value available to parent process?


From: Greg Wooledge
Subject: Re: sub-process changing value available to parent process?
Date: Wed, 8 Apr 2020 07:53:58 -0400
User-agent: Mutt/1.10.1 (2018-07-13)

On Wed, Apr 08, 2020 at 08:24:05AM +0200, Sylvain Viart wrote:
> I'm exploring bash possibilities to return multiples variables from a
> child process to a parent script.

> I know it can be accomplished by eval() but I'm exploring alternative
> way to pass complex result, while keeping it safe, and efficient.

> I tested:
> 
> eval "$(child --arg --more -v -p filenam)"

> source child_companion.sh --some-arg  --more  -v -p filename

> source <(child --produce-bash --some-arg  --more  -v -p filename)

The first and third are the same thing, except that the third one uses
a process substitution (background process feeding data through a FIFO),
while the first one uses a command substitution (foreground process
feeding data through a pipe()).

They both evaluate the data that's sent through the FIFO/pipe() in exactly
the same way.

If you think that by replacing "eval" with "source" you have somehow
improved "safety", you are gravely mistaken.

The second one is different, because ALL of the side effects of the
second script happen in the first script's memory space.  If the second
script sets variables without writing about it on stdout, or changes
directory, or opens/closes file descriptors, or defines functions, or
does anything else at the global scope, all of those changes are "live"
in the first script.

> I also tested an IPC with trap and signaling the parent that something
> is ready for reading, the parent passing the /dev/shm temporary file

Why do you need a signal?  If the child is synchronous, the parent knows
when the child is finished.  You might as well just write the name of
the temporary file to stdout, have the parent capture that in a standard
command substitution, and then source the temp file.

But then again, that's still no different from just writing the code
that you want the parent to evaluate to stdout, capturing it with an
ordinary command substitution, and then using eval.

They all do the same thing.

> JSON=$(./child --json --more "$@")
> export JSON

Why export?

> some_var=$(./child get  mykey)
> some_array=( $(./child get  mykey_array) )

What on earth... where's jq or jshon?  Are you calling the child once
to generate JSON, then calling it again to PARSE the JSON that it
already created?  This is silly.

You want an alternative?  OK, here's one:

Instead of returning a blob of eval-able shell code like:

var1='value one'
var2=(an array "here, sir")
declare -A var3=([type]=associative [foo]=bar)

Devise an encoding of your own that permits the child to send a stream of
key/value tuples.  One such encoding would be JSON, but bash does not have
the builtin tools to parse the content out of JSON, so this is not really
an efficient choice.

Another such encoding might be something like:

varname NULBYTE content NULBYTE varname2 NULBYTE content2 NULBYTE ...

This works pretty well for string variables; not so well for array
variables, as you still have to encode the array somehow, and
communicate which type of array each variable is to become.

I still don't see any real advantage of any of these schemes when
compared to the standard, completely sensible, perfectly safe, and
widely used:

### child
declare -p var1 var2 var3

### parent
eval "$(child)"

You're making your life stupidly complicated, but you haven't said WHY.
So, I'm simply guessing it's because of ignorance or stubbornness, or
most likely a combination of the two.

(Hint: the main reason one might pursue alternative key/value encoding
schemes is when the child is written in some language other than bash,
and therefore doesn't have the "declare -p" command to generate safely
eval-able code.)

(Hint2: if the child's language is sh, there aren't any array variables
to pass back -- every variable is a string variable.  And while sh
doesn't have declare -p, you can still use what I call "sh encoding",
which is: replace all single quotes with the four characters '\'' and
then enclose the value in single quotes.  The result of this sh encoding
is safely eval-able by sh, or by bash.  Of course, sh itself can't do
that encoding, so you usually end up calling sed.  Bash can use its
extended parameter expansions.)

tl;dr: "y u no use declare -p and eval"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]