I'm trying to modify an existing shell script to accept user input and handle some system exports. The below is an excerpt from a larger script. After running this script, I echo $TEST_DIR and I don't get anything back. Any ideas?

#!/bin/sh

if [ -z "$TEST_DIR" ]
then
    echo "TEST_DIR was not set, please enter the path: "
    read input_variable
    export TEST_DIR=$input_variable
    exit 1
fi
link|improve this question

Try source ‘filename’. – Gandaro Mar 12 at 18:22
You are exiting from this so it seems you are calling this in a child shell and that must be the reason why the variable is not visible. How are you invoking it? Invoke it in the existing shell i.e. by prefixing is with . i.e. instead of using myScript use . myScript. – amit_g Mar 12 at 18:23
feedback

3 Answers

up vote 2 down vote accepted

Save this as script.sh.

#!/bin/bash

if [ -z "$TEST_DIR" ]
then
    echo "TEST_DIR was not set, please enter the path: "
    read input_variable
    export TEST_DIR=$input_variable
fi

And run it like this:

. ./script.sh

Or, equivalently:

source ./script.sh

source runs the script in the current environment and consequently lets you modify the environment in the script. Without it every command, which runs as a child of the shell process, is only given a copy of the current environment.

Note I removed the exit line, as it would terminate the shell in this case.

link|improve this answer
feedback

The problem is that you're running the script in a subshell - it's setting your TEST_DIR properly, but then the shell exits, and the parent shell doesn't keep the change.

You might be better off making this a function you can source from the parent shell. Shell scripts can't modify the environment of the calling shell, but a function can modify the shell it's executing in.

link|improve this answer
feedback

You probably don't want to do exit 1; that is used to indicate failure. You'd use exit 0 to indicate success — but, as described below, you don't want to do that, either, in this case.

The other problem is that if you run the script as child process, it cannot affect the environment of the parent process.

To work around that, in POSIX shells, you need to use:

. your_script.sh

or, in bash, you can also use:

source your_script.sh

The script does not have to be executable, just readable, and will be searched for on $PATH unless you specify a name containing a slash, just like other commands.

And, when you do the . or source, you definitely do not want any exit in the script because that will cause the main shell to exit. The shell reads the file as if you were typing it at standard input (more or less), so an exit that's executed will exit the shell.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.