You're going to have problems...
The Bash shell is a very wily creature. Before you execute anything, Bash comes in and interpolates your command. Your command or shell script never sees whether or not you have a variable as a parameter.
$ set -x
set -x
$ foo=bar
+ foo=bar
$ echo "$foo"
+ echo bar
bar
$ set +x
The set -x
turns on debugging mode in the shell. It shows you what a command actually executes. For example, I set foo=bar
and then do echo $foo
. My echo
command doesn't see $foo
. Instead, before echo
executes, it interpolates $foo
with bar
. All echo
sees at this point is that it's suppose to take bar
as its argument (not $foo
).
This is awesomely powerful. It means that your program doesn't have to sit there and interpret the command line. If you typed echo *.txt
, echo
doesn't have to expand *.txt
because the shell has already done the dirty work.
For example, here's a test shell script:
#! /bin/sh
if [[ $1 = "*" ]]
then
echo "The first argument was '*'"
else
"I was passed in $# parameters"
fi
Now, I'll run my shell script:
$ test.sh *
I was passed in 24 parameters
What? Wasn't the first parameter of my script a *
? No. The shell grabbed *
and expanded it to be all of the files and directories in my directory. My shell script never saw the *
. However, I can do this:
$ test.sh '*'
The first argument was '*'
The single quotes tell the shell not to interpolate anything. (Double quotes prevent globbing, but still allow for environment variable expansion).
This if I wanted to see if my first parameter is a variable, I have to pass it in single quotes:
$ test.sh '$foo'
And, I can do this as a test:
if [[ $1 != ${1#$} ]]
then
echo "The first parameter is the variable '$1'"
fi
The ${1#$}
looks a bit strange, but it's just ${var#pattern}
. This removes pattern
from the left most side of $var
. I am taking $1
and removing the $
if it exists. This gets expanded in the shell as:
if [[ $foo != foo ]]
which is true.
So, several things:
- First, you've got to stop the shell from interpolating your variable. That means you have to use single quotes around the name.
- You have to use pattern matching to verify that the first parameter starts with a
$
.
- Once you do that, you should be able to use your variable with
${$1}
in your script.
"${!VAR}"
is ? I understand how it works, because that's exactly what i was looking for, but I didnt find it. :) – Lobeline