2

I constructed a simple example to illustrate the problem:

caller.sh:

#!/usr/bin/env bash
state="loaded"
source "sh/callee.sh" 2>&1
echo "$state"

callee.sh:

#!/usr/bin/env bash
state="integrated"

when I run caller.sh, it gives the result I want:

integrated

But if I add a pipe after the source command:

caller.sh:

#!/usr/bin/env bash
state="loaded"
source "sh/callee.sh" 2>&1 | cat
echo "$state"

The result becomes:

loaded

Question: How can I preserve/retrieve the changed value of $state in caller.sh?

2
  • pipe-line forks a sub-shell, the value is lost, once the sub shell terminates Commented Mar 2, 2017 at 18:05
  • 1
    What is your intention using cat in the first place? Commented Mar 2, 2017 at 18:08

1 Answer 1

3

You can't use a pipe. The source command runs in a subshell that exits after the pipe completes, so state is never set in the shell that calls echo "$state". You can use process substitution to "invert" the pipeline:

state="loaded"
source "sh/callee.sh" 2>&1 > >(cat)
echo "$state"

Now source executes in the same shell.

Sign up to request clarification or add additional context in comments.

3 Comments

But why is cat needed at all here?
what does the first > do?
cat is just something I came up with in this example. In my program I want to direct stdin and stderr to a log file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.