Shell Scripting – Variables

0
83
Shell Scripting Variables

Getting more into Shell Scripting we are going to take a look at variables as in every programming language in the world the concept of variables is very common basic. Variables are a symbolic name that is assigned to a chunk of memory where our values will be stored, read and changed when the time comes. Bourne Shell (Bash) is no exception so in this section, I am going to introduce you to the concepts of Shell Scripting Variables.

Furthermore, as this is quite a long topic I will be covering the advance stuff related to variables like setting the variables as an environment variable and much more.

So to better understand we can take a look at our first example as that can also be done by using variables. As it is such a simple example that it really doesn’t need variable but just for the understanding let do it anyway.

Note that there must be no spaces around the “=” sign: VAR=value  works; VAR = value doesn’t work. In the first case, the shell sees the “=” symbol and treats the command as a variable assignment. In the second case, the shell assumes that VAR must be the name of a command and tries to execute it.

Also Read: Introduction to Shell Scripting

If you think about it, this makes sense – how else could you tell it to run the command VAR with its first argument being “=” and its second argument is “value”?

Let’s see the example code:

#!/bin/sh
start="Hello World"
echo $start

So, if we look at this code what we are doing over here is that creating a variable by the name of start and then we are assigning it the value of "Hello World" then we are using echo to print the value stored in the variable.

Note that when assigning a string value to a variable we need to write the value within quotes this is because when we do echo Hello World echo command takes the number of parameters whereas a variable can contain only one value so when assigning a string value which has spaces in it we have to write that in quotes.

If you have used Python before you might remember that the variables used in Python don’t have a data-type you can simply write a variable and then assign the values to those variables. It is the same case with Bash variable can store strings, integers and real number or anything you like.

But there are Stored routines or function within Bash that only take numbers as an input or some functions that only accept strings like in seeing the following example:

Note: You can type this directly in the Terminal Window.

$ x="Osama"
$ expr $x + 1
expr: non-numeric argument
$

So you can see that if we  try to use expr to add 1 to our string variable we get an error that it’s not a numeric argument that is because expr only take numbers as an input and then apply the numeric operation on them like addition, multiplication, etc.

But there is no difference between:

start="Hello World"
msg=hi
number=1
pi=3.142
pib="3.142"
mixed=123abc

Note though that special characters must be properly escaped to avoid interpretation by the shell. This is discussed further in the Shell scripting topics.

Now we will look at how we can take input from the user and assign the value to the variable that can be done by using the read command. The following script will ask the user to input their name and then will echo it out.

#!/bin/sh
echo What is your name?
read name
echo "Hello $name- Good Morning."

This is using the shell-builtin command read which reads a line from standard input into the variable supplied.

Note that even if you give it your full name and don’t use double quotes around the echo command, it still outputs correctly. How is this done? With the start variable earlier we had to put double quotes around it to set it.
What happens, is that the read command automatically places quotes around its input, so that spaces are treated correctly. (You will need to quote the output, of course – e.g. echo "$MY_MESSAGE").

Scope of Variables

Variables in the Bourne shell do not have to be declared, as they do in languages like C. But if you try to read an undeclared variable, the result is the empty string. You get no warnings or errors.

There is a command called export which has a fundamental effect on the scope of variables. In order to really know what’s going on with your variables, you will need to understand something about how this is used.

Let’s explain it using a script:

#!/bin/sh
echo "My Name is: $name"
name="Osama"
echo "My Name is: $name"

Save the script 1.sh Now, let’s run the script:

./1.sh
My Name is:
My Name is: Osama

What is happening over here? The reason that we don’t see the name in the first line is that we haven’t assigned the value to that variable so it doesn’t give any output there but at the second as we have actually created and assigned the value to that variable and we can see it in the output of line three.

If we run the script again we will get the same output that is because of #!/bin/shWhenever we run the script because of this as it will create another interactive shell and then execute the script so the variable is not accessible outside of the current shell.

So in order to make it accessible globally, we need to export this variable type this in the terminal:

$ export name
$ ./1.sh
My Name is: Osama
My Name is: Osama

So let’s take a look at this in another way what if you have created a variable which is globally accessible and the assigned the value to it from the terminal and then the variable inside the script is changing the value of that variable to “Osama” but when you echo the variable after the execution what will be the output:

$ name="Hacker"
$ ./1.sh
My Name is: Hacker
My Name is: Osama
$ echo $name
Hacker
$

This is because, Once the shell script exits, its environment is destroyed. But name keeps its value of Hacker within your interactive shell.
In order to receive environment changes back from the script, we must source the script – this effectively runs the script within our own interactive shell, instead of spawning another shell to run it.
We can source a script via the “.” (dot) command:

$ name="Hacker"
$ . ./1.sh
My Name is: Hacker
My Name is: Osama
$ echo $name
Osama
$

The change has now made it out into our shell again! This is how your .profile or .bash_profile file works, for example.
Note that in this case, we don’t need to export name.

One other thing worth mentioning at this point about variables is to consider the following shell script:

#!/bin/sh
echo "What is your name?"
read USER_NAME
echo "Hello $USER_NAME"
echo "I will create you a file called $USER_NAME_file"
touch $USER_NAME_file

Think about what result you would expect. For example, if you enter “osama” as your USER_NAME, should the script create osama_file?
Actually, no. This will cause an error unless there is a variable called USER_NAME_file. The shell does not know where the variable ends and the rest starts. How can we define this?
The answer is, that we enclose the variable itself in curly brackets:

#!/bin/sh
echo "What is your name?"
read USER_NAME
echo "Hello $USER_NAME"
echo "I will create you a file called ${USER_NAME}_file"
touch "${USER_NAME}_file"

The shell now knows that we are referring to the variable USER_NAME and that we want it suffixed with “_file“. This can be the downfall of many a new shell script programmer, as the source of the problem can be difficult to track down.

Also, note the quotes around "${USER_NAME}_file" – if the user entered “Osama Mahmood” (note the space) then without the quotes, the arguments passed to touch would be Osama andMahmood_file – that is, we’d effectively be saying touch Osama Mahmood_file, which is two files to be touched, not one. The quotes avoid this.

This is it for this article if you liked it do share and let us know in the comments if we missed something.