3

I am trying to export variables from one script to the main script and passing one of the imported variables as argument to the main script.

Here is the script fruitcolour.sh having variables only :

apple="Red"
mango="Yellow"
orange="Orange"
pear="Green"

Here is the main script GetFruitColour.sh :

#!/bin/bash

source fruitcolour.sh

echo "The colour of " $@ " is " $@ "."

For passing apple as argument, I want to get the value of variable apple i.e. Red .

So, When I run ./GetFruitColour.sh apple

It must give output :: The colour of apple is Red.

6

One way to accomplish this is through indirection -- referring to another variable from the value of the first variable.

To demonstrate:

apple="Red"
var="apple"
echo "${!var}"

Results in:

Red

Because bash first takes !var to mean the value of the var variable, which is then interpreted via ${apple} and turned into Red.

As a result, your GetFruitColour.sh script could look like:

#!/bin/bash

source ./fruitcolour.sh

for arg in "$@"
do
  printf 'The colour of %s is %s.\n' "$arg" "${!arg}"
done

I've made the path to the sourced script relative instead of bare, to make it clearer where the file is (if the given filename does not contain a slash, shells will search the $PATH variable for it, which may surprise you).

I've also changed echo to printf.

The functional change is to use the looping variable $arg and the indirect expansion of it to produce the desired values:

$ ./GetFruitColour.sh apple mango
The colour of apple is Red.
The colour of mango is Yellow.

Do note that there's no error-checking here:

$ ./GetFruitColour.sh foo
The colour of foo is .

You may find it easier to use an associative array:

declare -A fruits='([orange]="Orange" [apple]="Red" [mango]="Yellow" [pear]="Green" )'

for arg in "$@"
do
  if [ "${fruits["$arg"]-unset}" = "unset" ]
  then
    echo "I do not know the color of $arg"
  else
    printf 'The colour of %s is %s.\n' "$arg" "${fruits["$arg"]}"
  fi
done
  • That's the most concise explanation of !var that I've seen. – Tim Kennedy May 30 at 16:24
  • It worked great. Thank you for explaining. – jonny789 May 30 at 16:52
  • The only point to add: for arg in "$@" boils down to mere for arg. – jno May 31 at 7:55
3

You need to use an indirect variable reference:

If the first character of parameter is an exclamation point (!), and parameter is not a nameref, it introduces a level of indirection. Bash uses the value formed by expanding the rest of parameter as the new parameter; this is then expanded and that value is used in the rest of the expansion, rather than the expansion of the original parameter. This is known as indirect expansion.

fruitcolor.sh:

#!/bin/bash

source fruitcolor.sh

echo "The color of $1 is ${!1}"

$ ./getfruitcolor.sh apple
The color of apple is Red

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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