Scripting is the process of taking a set of commands you’d normally run by hand and putting them in a file to automate the process. Bash is one of the most common languages used for scripting. While scripting is a subset of programming, the act is usually called “programming” once higher level language features come into play, like control flow, loops, and modules.
We’re going to introduce you to scripting in this class for two reasons:
Once we get a collection of lines together, it’s handy to put them in a file so that we can run them repeatedly. There are very few parts to a Bash script file. Let’s look at an example:
First, notice the top line. This is what’s called a shebang, and is basically just a line of code that tells the shell what program we want to run the contents of this file. We’re writing a script in Bash, so we chose Bash. (We could have just as easily been writing a Python script and changed “bash” to “python”).
The rest of the file is just a sequence of Bash commands! That means we can do things like change directories and move files for example.
Note that if you saved the above file as “my-first-script.sh” and tried to run
it (./my-first-script.sh
), you’d get an error. We need to use chmod
to give
this file executable permissions:
chmod +x my-first-script.sh
One thing we often like to do is debug our scripts. Print statements are a great way to do this.
To print text, you can use the echo
command, which just prints its arguments:
Bash keeps a collection of “environment” variables for every user who’s logged
in. These variables hold key pieces of information about what’s going on. For
example, there’s a variable called SHELL
that says what shell you’re running,
a variable named USER
which contains the username of the current user, another
named PWD
that contains the present working directory, and more.
You can control your environment by setting certain variables. Here are a few examples of how that’s done:
The difference between using export
and not using it deals with what programs
are able to read the contents of that variable. If a variable is not exported,
then only you will be able to read its contents. That is, none of the programs
that you run will be able to see the value of the variable that you just set.
It helps to be able to check and print the value of environment variables! To
access to contents of a variable, you have to use the $
operator.
Note that in the last example only lone
was printed. In Bash, all variables
are treated as the empty string if not initialized, which was the case here.
Not using {...}
made the difference of not using the right variable name,
causing something wrong to be printed.
Note: you should know that permissions exist, but we don’t expect you to memorize this. Feel free to skim.
To learn a little bit more about why we have to run chmod
to execute
scripts, let’s dive into file permissions. File permissions are a way to control
what kinds of things can be done to a file, and by whom.
In Unix, there are three granularities at which access can be controlled:
u
)g
)a
)Additionally, there are three actions that can be granted on a file:
r
)w
)x
)Combined, that’s 3 x 3 = 9 permissions. We can see these in action using ls
-l
. The first column of output contains the permissions:
The first column tells us whether it’s a directory, but the next 9 tell us r
,
w
, and x
for the user, group, and all, in that order. A hyphen means that
permission is not enabled.
If we’re thinking like hackers, we’d represent this information using 9 bits. And if we use a fancy numbering system called “octal” where numerals range from 0 to 7 and take up 3 bits per numeral, we can write a permission using 3 octal numerals. For example:
(We don’t usually get 1, 2, and 3, because that would mean we can’t read the file, but we can write or execute it, which doesn’t usually make sense).
With our new numbering scheme, we can reinterpret our sequences of rwxrwxrwx
:
rwxrwxrwx
= 777rwxr-xr-x
= 755rw-r--r--
= 644rw-------
= 600chmod
When you’re invoking chmod
, you have a number of ways to invoke it: