To summarize, you want to retrieve a value out of script1.sh
without running all the commands in script1.sh
. I will assume that script1.sh
is not under your control, possibly because it is vendor-provided, or managed by an obstinate colleague, or similar such issue, which makes it so that script1.sh
has to be used as is.
I will present two approaches. The first is good for getting specific variables out of script1.sh
, one at time:
var=$(awk -F'"' '/^variable=/ {print $2}' script1.sh )
echo $var
This uses awk
to read (not execute, just read) script1.sh
. awk
looks for the line that begins with variable=
and then writes what appears after the double-quote mark on that line. The output from awk
is capture into variable var
.
In more detail:
The statement is of the form var=$(...)
. This means that whatever is in the parentheses is run as a bash command and its standard output is assigned to the variable var
.
Inside the parentheses, we have the awk
command: awk -F'"' '/^variable=/ {print $2}' script1.sh
. Let us consider it in parts.
awk
breaks lines (records) into fields. -F'"'
tells awk to use double-quote as a field separator.
/^variable=/
tells awk
to restrict operation to lines that begin with variable=
. Thus, all the miscellaneous commands in script1.sh
will be ignored.
{print $2}
tells awk
to print the second field. This means whatever is between the first and second occurence of a double-quote character.
The last argument to awk
tells it what file to read: script1.sh
.
The above approach is good for handling one variable at a time and allows you to rename the variable if you like.
How to handle many variables
If you want to source all the variables assigned in script1.sh
, consider:
source <(grep -E '^\w+=' script1.sh)
This uses grep
to extract all lines from script1.sh
that look like variable assignments. These lines are then run in the current shell, assigning the variables.
If you use this approach first check to make sure that you want all the variables and that there aren't any that will interfere with what you are doing. If there are such, we can exclude them with a second grep
command.
Considering the pieces in turn:
source file
tells the shell to execute the file
in the current shell.
<(...)
is called process substitution. It allows us to use the output of a command in place of a file name.
The command grep -E '^\w+=' script1.sh
extracts all lines that seem like variable assignments. If you run this command by itself on the command line, you should see something like:
variable="Hello"
var2="Value2"
and so on. You should do this first and inspect the output to make sure that these are the lines that you want to execute.
grep -E '\w+='
is equivalent togrep '\w='
and would match onconfigure --prefix=/opt/foo
orecho foo=bar
for instance. You may want to be a bit more restrictive, like ingrep -E '^[[:blank:]]*[_[:alnum:]]+='
(note that\w
is not portable). That's still no fool-proof but probably more reliable. The next big issue would be lines likeENVVAR=value some-command...
– Stéphane Chazelas Jun 09 '14 at 07:05