Reputation: 439
I am new to shell scripting. I have a very basic question about how we read variables defined in our terminal as input to a shell scirpt.
let us say i defined this variable in my terminal
a=22
if i do echo $a
it gives 22 as output in my terminal.
I wanted to pass this variable as a parameter to a script named input.sh
#!/bin/bash
echo "Enter variable name:"
read Input
echo $Input
I ran the scirpt as ./input.sh It popped up the message as
Enter variable name:$a
But in the output i have $a as output not 22. I wanted 22 as output. Is there a way to do this?
Upvotes: 5
Views: 27172
Reputation: 167
The answers given are all fine, but personally I like to see clear examples. Here is a script in which you can add arguments and it will output the values of ${argument} alongside ${!argument}.
I hope this helps someone!
#!/bin/bash
num_args=$#
n=0
echo "Number of arguments is $num_args"
while [ "$n" -ne "$num_args" ]; do
((n++))
echo "Value for \"\$n\" is \"$n\", value for \"\${!n}\" is \"${!n}\""
done
Here is a sample run:
./myscript.sh abc 123 hello "A string with spaces needs quotes"
Output:
Number of arguments is 4
Value for "$n" is "1", value for "${!n}" is "abc"
Value for "$n" is "2", value for "${!n}" is "123"
Value for "$n" is "3", value for "${!n}" is "hello"
Value for "$n" is "4", value for "${!n}" is "A string with spaces needs quotes"
Upvotes: 0
Reputation: 663
To use the variables defined in the terminal in your bash script -
Change last line of your script so that it looks like -
#!/bin/bash
echo "Enter variable name:"
read Input
echo ${!Input}
Run your script input.sh on the terminal as -
. input.sh
And finally, when you input the variable name, do not use $ sign. For e.g. -
6c4008a16b7c:~ z001lg8$ . input.sh
Enter variable name:
a
22
6c4008a16b7c:~ z001lg8$
Voila, you can now use the variables defined in the terminal in your script.
Explanation -
In your script, $Input is changed to ${!Input} so that the content of the user input(which is variable name) is echoed and not the variable name itself. As explained by @Fred - $1 means "the content of variable 1", ${!1} means "the content of the variable that is named $1".
When script is run as . input.sh
, it means that you are sourcing the script contents on the terminal. The .
symbol is used for sourcing a command/script.
The $
sign is not required when the variable name is entered in terminal because ${!Input}
format already takes into account that the value in Input
variable is a variable name.
Upvotes: 1
Reputation: 6995
You are mixing several things here. Where to start...
The usual way to pass values to a script is through positional parameters.
Suppose you have this script, called s1
:
#!/bin/bash
echo "First two args are: $1 $2"
If you execute it like this :
./s1 Arg1 Arg2
You will see the following output :
First two args are: Arg1 Arg2
If you want to pass a variable name to the script, and have that script output the value of this variable, then you must do two things. First, initialize the variable and export
it so that it can be seen by the children processes (including the script you will call, which is a separate process unless called with source
or .
).
VAR="Some value"
export VAR
You can also do both in a single statement:
export VAR="Some value"
Then, adapt the script to perform an indirect access to the variable :
#!/bin/bash
echo "Value of variable named $1 : ${!1}"
Please note that while $1
means "the content of variable 1", ${!1}
means "the content of the variable that is named $1
". This is the indirect part.
Now, if you want to take it a step further, and allow the script to interactively read user input (not an argument) and use the value read as a variable name to expand, you would do something like this :
#!/bin/bash
echo "Please enter a variable name"
read VARNAME
echo "Value of variable named $VARNAME : ${!VARNAME}"
Using positional parameters makes the script easier to reuse in non-interactive scenarios, so reading user input should be limited to cases where it is necessary.
The above is to help understand the basics. If you move beyond toy scripts, you will need to understand the security implications of indirect access (especially if you allow user input). You will also need to validate positional parameters or user input are valid for your purpose (i.e. contains a valid variable name) so that you may have your script react appropriately. Well, you would probably need to check if positional parameters were even provided to begin with. All of this is doable in shell scripting, but is beyond the scope of a single question. In any case, checking input (and also errors) will be required if you intend to have robust scripts in situations where reliability is expected.
Upvotes: 7