help-bash
[Top][All Lists]
Advanced

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

Re: The difference between `X=x f | cat` and `{ X=x; f; } | cat`


From: Kerin Millar
Subject: Re: The difference between `X=x f | cat` and `{ X=x; f; } | cat`
Date: Thu, 19 Jan 2023 15:49:06 +0000

On Thu, 19 Jan 2023 09:10:19 -0600
Peng Yu <pengyu.ut@gmail.com> wrote:

> On 1/19/23, Kerin Millar <kfm@plushkava.net> wrote:
> > On Thu, 19 Jan 2023 08:02:07 -0600
> > Peng Yu <pengyu.ut@gmail.com> wrote:
> >
> >> Hi,
> >>
> >> f is a function that uses a variable called X, which is not declared in
> >> f.
> >>
> >> As far as I can tell, the following two ways produce the same results.
> >>
> >> - `X=x f | cat`
> >> - `{ X=x; f; } | cat`
> >
> > They are not equivalent.
> >
> > $ bash -c 'f() { declare -p X; }; X=x f; declare -p X'
> > declare -x X="x"
> > bash: line 1: declare: X: not found
> >
> > $ bash -c 'f() { declare -p X; }; X=x; f; declare -p X'
> > declare -- X="x"
> > declare -- X="x"
> >
> > The first version defines X in such a way that it affects only the operating
> > environment in which f is run. Note, also, that the variable is marked as
> > being exportable, meaning that it would be present in the environment of any
> > subprocesses that might be launched by f. For a more rigorous explanation,
> > refer to the SIMPLE COMMAND EXPANSION section of the manual.
> >
> > The second version just defines X as an ordinary shell variable then
> > proceeds to run f. The use of a { list; } ensures that both of those things
> > happen within the same subshell - the one implied by the left hand side of
> > |.
> 
> In my question, X is never accessed after calling f.
> 
> Let's put my question this way to make it clearer.
> 
> Suppose that in `X=x f | cat`, f is a function, that uses X read-only,
> no external commands called by f directly or indirectly use X. And I
> know that `{ X=x; f; } | cat` produces the same results that I care
> about (for example, X=x is available even after f is something I don't
> care).
> 
> In this case, is `{ X=x; f; } | cat` faster than `X=x f | cat`?

I would consider it highly unlikely but would also suggest that you conduct 
your own benchmarks.

time for ((i=0; i < 1000; i++)); do X=x f | cat >/dev/null; done
time for ((i=0; i < 1000; i++)); do { X=x; f; } | cat >/dev/null; done

Obviously, you may need to tune the number of iterations in order to incur an 
acceptably substantive wall time.

-- 
Kerin Millar



reply via email to

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