We'll now look at how to use scripting to automate system maintenance tasks.
Now, when we log into a Linux operating system,
we're automatically dropped into a command-line like this.
What actually happens is after we successfully log in a program called
bash opens up and we are dropped within its text based environment.
All the commands we type are interpreted by bash which
figures out what needs to happen to execute them.
And that's why bash is also called a command interpreter or a shell.
Now, in this case, we're using it interactively, we write something,
we press enter, it gets executed and we get a result.
But bash can be used in a different way with scripts.
Now,
scripts are simply files where we can
add multiple instructions for our command interpreter.
The interpreter can then read this file and execute the instructions in order
first, it will execute the instruction on the first line,
then the one on the second line and so on.
But it's easier to understand how scripts work if we build one.
So let's start experimenting
first, we'll create a file called script dot sh.
Now standard practice to add the dot sh extension to this file, it's not mandatory,
but it makes it easier when you type in LS
in a directory to spot which files or scripts.
On rare occasions,
we might need to skip adding the dot sh
extension if we want other programs to execute them.
And we'll see an example of this when we
learn about scheduling tasks in a later session.
Now let's edit script dot sh and add some content.
This first line is very important
and we'll write this here
pound sign, exclamation point slash bin slash bash.
Now to make our script work, this has to be on the first line,
not the second or the third also make sure there's no space before the pound sign.
Now this is called a shebang.
And what the shebang does is it's the full path to
the command interpreter that we want to run the script.
And in this case, we chose slash bin slash bash, which is bash.
Now in the third line, we can add this.
Now the pound sign at the beginning of the line marks this as a comment.
A commented line is something that the command interpreter will ignore.
It will not execute anything here. No matter what we type. A
comment is useful when we want to document our script to inform other
people that may read it about what our lex line or lines do.
Also,
it might be you coming back to the script
six months later and you're writing comments for yourself.
Now, on the next line, we'll add an actual command to this script.
The date command prints out a date and time.
We can also use redirection to save the output of the
date command to the slash temp slash script dot log file.
We're essentially building a simple log from within our script
note how we can write these commands the same way we write them at the command-line,
we can redirect output errors, pipe to other programs and so on.
Now, in the next line,
we'll add this command slash proc slash version is a special file that has
detailed information about the current Linux kernel
version that's running on our operating system.
So we're sending the content of the special file to
our log file at slash temp slash script dot log
in a nutshell.
We built a script that can keep track of what
kernel versions ran on our server in the past.
Now let's press escape
then colon
WQ
and enter to save our file
to be able to run this script. We must now make it executable.
If we only want the owner of this file, our current user to be able to execute it,
we can add this permission
or if we want everyone to be able to execute it,
we can just run this.
This will grant execute permissions for everybody,
the user owner, the group owner and others
to run this. We must either provide the full path to the script and type this
or we can type this, the dot represents our current directory.
So when we type in dot slash script dot sh,
the dot becomes slash home slash Aaron. Since we're already inside this directory,
the dot represents our current directory.
So when we type in dot slash script dot sh,
the dot becomes slash home slash Aaron, since we're already inside this directory
slash script dot sh is added at the end.
So it's the same as typing in slash home slash Aaron slash script dot sh.
And let's see what our script did.
We'll read the script dot log file
pretty nice result.
Now, further down the line,
we could set this up to automatically run each day and we'll
have a log with all Linux kernel versions that we ever used.
When something malfunctions, you could consult this log and say, hey,
this problem started when we updated to the 5.15 dot X version.
So that's the core part of writing a script.
You must make a file executable and then you add in its
contents with a shebang pointing to the path of the command interpreter,
followed by some instructions for that interpreter.
However,
smarter scripts can be created with the help of what are called bash builtins.
And to get a quick list of the available builtins type in help,
there are many available,
but we'll explore two of these to get a glimpse of what they make possible.
We'll look at if and test.
Let's create a different script to archive the
contents of the slash Etsy slash app directory.
Now, we can run this command even if archive dash
app dot sh doesn't exist, Vim will create it automatically once we save the content.
Let's imagine we want this script to back up
the contents of the slash Etsy slash app directory.
We'll use Tar to create an archive that will be
saved at slash temp slash archive dot Tar dot GZ.
Once the file is created, we'll make the script executable
and run it.
And we see that indeed,
our simple script created in an archive with the content of the
Etsy slash
app directory.
And we can look at the list of files inside using Tar TF.
But now imagine this someone accidentally deletes some files in slash Etsy slash
A.
Next our backup script runs
then
slash temp slash archive dot par GZ getss created
overwriting the previous backup.
Well,
now we're left with a broken Etsy app directory and also a broken slash
temp slash archive dot TGZ since it backed up the broken Etsy app directory,
if only we still had the old backup around
the one that contained the old content of slash Etsy slash app, which was still good.
Well, we can make our script smarter, we can make it implement the following logic.
We can check to see if slash temp slash archive dot
TGZ
exists using if and test
two built in functions of bash.
If it does,
we can rename it to slash temp slash archive dot Tar dot
GZ dot old and then create a new slash temp slash archive dot
TGZ.
Now, we'll always have two backups, the new one and the previous older one.
Now, if archive dot Tar dot GZ does not exist,
it will simply create the first backup in the series.
And as mentioned, we'll use if and test bash builtins to make this possible
to get information about a builtin and its syntax use help followed by its name.
For example, help if and help test.
Let's create a new script called archive dash
A
dash two dot sh
and add in this content that implements our desired logic.
Now let's analyze this line by line
if test dash F
archive dot Tar dot GZ then OK.
So if starts a condition check,
it verifies if the expression that comes after it is true or false.
And inside our condition, we use the test built in.
Now as help test command shows us
this can perform various types of check.
For example, for files,
it can test if it's a certain type of file if you can execute it and so on.
In
this case, the dash F option makes it check the file at slash temp slash archive dot
TGZ
check if it exists as a regular file, if it does the test built in returns true.
If it doesn't, it returns false.
Now our if builtin cannot know where the condition check ends,
so we tell it where it ends by adding the semicolon at the end of the condition,
we want to be verified.
Finally, the word then signals what will happen if our test function returns true.
So when this is true, the following two commands get executed.
And this simply renames the preexisting archive dot
TGZ
file to archive dot Tar dot GZ dot old and then
creates a new archive named archive dot par dot GZ.
Now note how we have four spaces before each command.
This is just standard convention to make the script more easily readable
because the lines are moved to the right.
In this way, we can easily spot what will happen if our test function returns true.
And the next line is
this signals what will happen if our test
doesn't return true and it returns false instead.
In this case, this is what will happen if fl
temp slash archive dot
TGZ does not exist
if it returns false, a simple archive will be created
and it won't rename the old archive this time because there isn't one available.
Finally, on the last line, we have F I
which is just if in reverse this signals that this is the end of our if block.
Now let's save our script
and make it executable
and then we'll run it.
And if we look in slash temp, we'll see this,
which means our script is working as intended.
The old archive was moved to a file with the dot old extension
and a new archive was created.
So now we have both versions available.
It's important to note that almost any command can be used in an if block.
That's because most commands return a so called exit status code,
they return zero. If the command executed successfully,
they return a value larger than zero.
If the command didn't find what it was looking for, or if it encountered an error,
when it sees the command return zero,
it considers this to be returning true
when the command returns a nonzero value if
considers that command to be returned false.
For example, consider the grep command.
If it finds the text, you are looking for, it returns zero.
If it doesn't, it returns one,
so we can have a script like this.
So in this first line,
we're using grep to look at the Grub file and see if it has a timeout of five seconds,
right?
So grep looks for the number five in the Etsy default Grub file
and Q stands for quiet.
This option tells grep not to display match lines because
we don't need our script to output those lines.
In
this case, our script will output.
Grub has a timeout of five seconds if the number five was found
and it will output.
Grub does not have a timeout of five seconds if the number five was not found.
And now we make the script executable
and run it
and look at that. Grub has a timeout of five seconds.
These are the basics of scripting with bash builtins.
If you want your future scripts to implement more advanced logic,
you'll have to dive deeper into more builtins such as
for
and while loops functions, variables and so on.
These allow you to construct scripts in a way that resembles programming logic.
Thus, your scripts become more intelligent, so to speak,
and they can do even more interesting things.
And if you're in need of a quick refresh of how scripting works,
you could take a quick peek at files from the slash Etsy slash Chron dot daily,
weekly and monthly directories.
Usually all these files in here are scripts.
This way you can get sort of a cheat sheet for common script syntax
like the shebang on the first line and the syntax of F and so on
to learn more about shell scripts,
check out our shell scripts for beginners course on code cloud.
It's a project driven course with many hands on labs
that will help you learn with easy to understand
theory and also practical exercises you can go through.