Mini-Class: Shell Scripting, Day 2

Hi again and welcome to day 2 of your shell scripting course!

Yesterday you wrote a script named “day1.sh” that contained the following contents:

#!/bin/bash
echo "I don't have to be great to start, but I have to start to be great!"

Start off with a Shebang

Let’s take a closer look at the very first line of the script:

#!/bin/bash

This first line is a called a “shebang.” The reason why it’s called a shebang is that the pound sign (#) is sometimes called a sharp. If you can read music, you know that the pound sign looks very similar to a sharp sign in musical notation.  Many people call “#,” “sharp.” Also, the slang term for an exclamation point (!) is “bang.”

So, “#!” could be spoken as “sharp bang.” An inexact contraction of those words is “shebang.” That’s where the term shebang comes from.

You want to start out each shell script with a shebang followed by the path to an interpreter, which is /bin/bash in our case.

When you execute a shell script, the commands inside the script are interpreted by /bin/bash. Remember: the first line, the shebang, determines what program executes the commands listed in that file.

If you do not supply a shebang and specify an interpreter on the first line of the script, the commands in the script will be executed using the current shell.  That may not be what you want! For example, if you have some bash-specific items in the shell script and you happen to be using the csh shell, when you execute it you are going to end up with some errors.

This is really important if others are going to execute your scripts because you have no control over what login shell they will be using when they execute your script. That’s why it’s best to be very explicit and always use a shebang and supply the interpreter.

Executing Your Shell Scripts

Yesterday, you added executable permissions to your script and ran it:

$ chmod +x day1.sh
$ ./day1.sh

We already talked about the importances of permissions, but we didn’t talk about what is going on when you typed “./day1.sh” and hit enter.  Let’s break it down.

The period, which some people call a “dot,” represents “this directory”. For example, if you type “cd .” you wouldn’t go anywhere.  You wouldn’t change directories, because “.” IS the current directory.

On a related note, “..” represents the parent directory. If you type “cd ..”, you would move to the directory above the current directory you are in.

The forward slash is the directory separator. So, “./day1.sh” is the current directory followed by a directory separator followed by the script name.

That’s how you execute a script in your current directory: ./name-of-the-script.sh

This is equivalent to using the full path. In my case, I could actually run /home/jason/day1.sh to accomplish the same outcome.

The reason why “./” works is that “.” represents the current directory which is /home/jason. Then we specify “/” which is the same as /home/jason/.  Finally, we provide the name of the file which is the same as the name of this file: /home/jason/day1.sh.

Long story short, just remember this pattern:

chmod +x script
./script

Echo . . . Echo . . . . Echo . . . . .

The other line in the “day1.sh” script is this:

echo "I don't have to be great to start, but I have to start to be great!"

As you probably figured out by now, the echo command just displays whatever is passed to it.

But where does echo come from?

It’s actually a shell builtin which means it is a command that is built into the shell and doesn’t require any external programs to execute. It’s part of bash.

How do you know that it’s a shell builtin?  You can use the “type” command (which is also a shell builtin, interesting enough) to show you if a given command is a shell builtin or not.

$ type echo
echo is a shell builtin

If you want to see all instances of “echo” on your system, use the “-a” option to type:

$ type -a echo
echo is a shell builtin
echo is /usr/bin/echo

(NOTE: depending on your specific setup you might see slightly different output.  For example, instead of “/usr/bin/echo” you might see “/bin/echo”.  Don’t worry. The *concept* is the same even if the details differ slightly.)

The type command lists the echo commands in the order that they will execute. The shell builtin is listed first, so that is what gets executed when you type “echo” and press Enter. Even though I don’t recommend it, you can force the execution of the second option by using its path:

/usr/bin/echo "Hello world."

Anytime there is a shell builtin, use it. Do NOT specify the full path. Using shell builtins is slightly more efficient because the shell doesn’t have to request an external program to do the work.

The most import advantage of using shell builtins is that your scripts become portable. For example, if the echo command is located at “/bin/echo” on some systems and “/usr/bin/echo” on other systems then you might run into an issue by specifying the full path. When you use the shell builtin you avoid that issue.

You can think of builtins as “free stuff” you get by using Bash. In addition to builtin commands, there are other builtins including variables that you’ll be learning about soon enough.

Write Your Next Script

Before we wrap up for the the day, let’s write a script using something new: a variable.

$ nano day2.sh

Type the following contents into the file. Be very careful to use the same spacing, case, and punctuation as shown below:

#!/bin/bash
SKILL="shell scripting"
echo "I want to be good at ${SKILL}.  That's why I practice ${SKILL}."

Give your script execute permissions and run it:

$ chmod +x day2.sh
$ ./day2.sh

If everything goes as planned, you’ll see the following text on your screen:

I want to be good at shell scripting.  That's why I practice shell scripting.

Variables

In the script you just created you assigned the value of “shell scripting” to the variable named SKILL:

SKILL="shell scripting"

Variables are simply storage locations that have a name. You can think of variables as name/value pairs. When you access the variable of “SKILL” the value that is returned is “shell scripting”.

Unlike some other programming languages, when you create a variable you don’t specify its type.  It doesn’t matter if the value is a string, an integer, or anything else. You simply assign the value to the variable.

It’s very important to know that there are no spaces around the equals sign. The syntax is:

VAR_NAME="value"

If you have a space before or after the equals sign you’ll get a “command not found” error message.

What You’ve Learned Today

In today’s lesson, you learned what a shebang is and the importance of using one.  You also learned that the echo command you used in your script is a shell builtin.  More importantly, you learned how to tell if a given command is a shell builtin or not.  Finally, you were introduced to variables.

Here’s What To Expect Next…

There’s plenty more to learn about variables, so that is where we’ll pick up tomorrow.  For example, you’ll learn why you capitalized the variable name in your script.  Plus, you’ll be introduced to even more new shell scripting techniques.

Until tomorrow…

Jason

P.S. If you’re ready to master shell scripting once and for all check this out.