2

I have a shell script (let's call it parent.sh) which calls another shell script (child.sh), passing it an argument.

The child script does some work and sets a value in a variable called create_sql. I want to access this create_sql variable from the parent script which invoked it.

I am calling the child script from within the parent script like this:

./child.sh "$dictionary"

and straight afterwards I have the line:

echo "The resulting create script is: "$create_sql

However, there is no value being output, however, in the child script I am doing the same thing and the variable is definitely set.

How can I get this to work so that I can read variables created by the child script?

5
  • 1
    Succinctly, you can't do that unless you do something like . ./child.sh "$dictionary" (or in Bash, mimicking the C shell, source ./child.sh "$dictionary"). This reads and executes the script in the environment of the current shell, but could mess with other variables in the parent.sh script — there is no isolation between the scripts. Otherwise, a child process cannot sanely set the environment of the parent shell. (If you want to do it insanely, you can have the child shell run a debugger, attach to the parent shell process and set the environment that way — but 'insane' is polite). Commented Nov 13, 2014 at 6:57
  • Ok, how can I implement this functionality then? Should I just put the contents of the child script into the parent script? This was my attempt at modularizing the scripts.. Commented Nov 13, 2014 at 7:00
  • 1
    Arguably, the best way is to have the child.sh echo the value you want in $create_sql, and then you use create_sql=$(./child.sh "$dictionary") with no spaces around the assignment operator. Commented Nov 13, 2014 at 7:01
  • Child scripts can pass data to parents using exit codes, output streams, files. You could add some more less usual methods (such as signals), but environment variables are basically out. One common method is outputting something that can be eval-ed in the parent script (like ssh-agent: it will output SSH_AUTH_SOCK=something; export SSH_AUTH_SOCK; SSH_AGENT_PID=something; export SSH_AGENT_PID; and you would use it as eval $(ssh-agent ...) in the parent) Commented Nov 13, 2014 at 7:03
  • Oh cool! That actually makes a lot of sense - I'm new to shell scripting and this is really helpful. Commented Nov 13, 2014 at 7:04

2 Answers 2

4

Succinctly, you can't have a child script set a variable in the parent script unless you do something like:

. ./child.sh "$dictionary"

(or in Bash, mimicking the C shell, source ./child.sh "$dictionary"). This reads and executes the script in the environment of the current shell, but could alter any other variable in the parent.sh script; there is no isolation between the scripts. Otherwise, a child process cannot sanely set the environment of the parent shell. (If you want to do it insanely, you can have the child shell run a debugger, attach to the parent shell process and set the environment that way — but calling it 'insane' is being polite).

Arguably, the best way to get output from the child stashed in a variable in the parent script is to have child.sh echo the value you want in $create_sql, and then you use

create_sql=$(./child.sh "$dictionary")
echo "The resulting create script is: $create_sql"

with no spaces around the assignment operator. Note that the echo includes the variable inside the double quotes; this will preserve internal spacing (including newlines) in the variable's value. As written in the question, the variable is flattened into a space-separated stream of 'words' (sequences of non-spaces), losing any internal spacing.

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

Comments

0

Use the source Luke ! source word ( or . ) allows to run a script like if it was in current shell. beware, your script and the source one are 'married' :-) , sourced script have full access to all variables for the better or the worse...

Other ways implies to modify called script to put is result in a stream format that will be read by caller using script params | read VAR or RESULT=$(SCRIPT params) and echoing results from your called script

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.