posts   talks   feed   about   search  

Bash, an Introduction

by Mark Wilkinson · February 04, 2018

You’re comfortable with PowerShell and you’ve honed your T-SQL skills over the years, but what about the Bash scripting language? With the release of SQL on Linux a lot of DBAs are wondering how they might manage SQL on this new and unfamiliar operating system. While PowerShell Core is available and has come a long way, it still needs to be installed and certainly has some limitations. Bash on the other hand is available on almost any Linux system and can be incredibly powerful.

In this series, we’ll cover what Bash actually is, some of the basics of using Bash, and my own opinions on how to best structure your scripts. My goal is to give people that are unfamiliar with Bash a good place to start. Throughout this post I will try to link to external documentation as much as possible, as the Bash documentation is fantastic.

Also note that I will be trying to focus on writing scripts and less on individual commands. In this post we are going to start with writing a basic script to output information to the console.

What is Bash?

Bash (the Bourne Again Shell) was created in 1989 for the GNU Project as a free replacement for the Unix Bourne shell. Most modern Linux systems use Bash as their default command line shell, so if you have ever dropped to a command line on a Linux system, you have probably used Bash. Just like PowerShell, Bash is both a scripting language and a command shell/interpreter. So not only can you execute commands in an interactive shell session, but you can also write scripts that incorporate multiple commands.

Once you get your hands dirty with Bash you’ll notice a lot of features that were incorporated into PowerShell. Things like command substitution: $(Get-Date) were directly pulled from Bash $(date). Other features will look familiar as well, like the ability to pipe multiple commands together.

One thing you need to understand right away is that Bash is string based, not object based like PowerShell. This means you’ll find yourself doing a lot more string processing to get tasks done. Things like string splitting will be much more common. Bash does support objects, like arrays, but few if any commands output an array. As we go through this series you’ll see that this might not be as limiting as it sounds.

Setup

Before we can get started writing Bash scripts we need to get a few things figured out. If you are not familiar with Linux and the command line you are going to need to get an environment set up and figure out which tools you will use to write your scripts.

Test Environment

Hopefully if you are here you have somewhere to run Bash scripts. If not, you have a lot of options:

There are plenty of cloud providers you could use to spin up a Linux VM, but I listed Google Compute here specifically because you can get a VM in their lowest performance tier for free. It’s a great way to get started if you don’t have access to a Linux system and don’t want to make any changes to your system. All you need to get started is a Google account.

Choice of Text Editor

When it comes to your choice of text editor you have a lot of choices. By default most Linux distributions come with vi. There is a long -running war between users of emacs and vi. They both have their pros and cons so I am not going to tell you what to choose. I personally use vi, and you can find it on almost any Linux system. That being said, the learning curve is steep on both.

For those new to command line text editors I would suggest installing nano just to get started. Nano is available on most distributions and will be the closest thing to notepad.exe on the command line, documentation for using nano can be found here. Of course you can always use a graphical editor if you are working on a Linux desktop system or a Windows system with Bash installed.

Using the Examples

In all of our examples for the rest of this series, you’ll need to copy and paste the script code directly into a file with the .sh extension, and execute it. The .sh extension isn’t required but it makes finding script files in a directory listing a lot easier. Any time a command should be executed from a command line I will specifically call that out, and the example text will look like the following:

mark@atomo:~ >$ . ./myscript.sh  

In the code above mark@atomo:~ >$ is my command prompt, and . ./myscript.sh is the command we want to execute. The prompt shows the user and hostname, followed by the current directory. In this case our current directory is ~, this is a shorthand for the users home directory.

A Note About the Dot

In Bash, the . has a few special purposes. The first is in filesystem navigation and interaction. In those contexts the . represents the current directory so, in the example above, ./myscript.sh is referring to a script in our current directory. It’s important to note here that Linux uses the forward slash (/) as a path separator, instead of the backslash (\) used in the Windows world.

Another purpose for the . is in script execution. The command above starts with a . followed by a space. In Bash there is a special command called source. This command takes in a file and executes it. The . you see that begins the command above is simply a shortcut, or “alias”, to the source command. You could type: source ./myscript.sh, but using the . saves a few keystrokes. This is a way to execute script files that have not explicitly been set as executable.

Your First Script

No programming discussion is complete without the famous “Hello World” example. In this script we are introducing the “shebang” (#!), set options, and the echo command:

#!/bin/bash
set -e
set -u

echo "Hello World"

Copy the following above code into a file called hello_world.sh in your home directory (/home/<username> in Linux, c:\users\<username> in Windows). If you are using nano you would type:

mark@atomo:~ >$ nano hello_world.sh

Then paste the code, save the file, and exit back to the command prompt.

Explanation

Before we execute our script, lets go over what we are doing in the script.

First, all Bash scripts should start with the same line:

#!/bin/bash

The #! is known as a “shebang” in the Linux world, the path following the shebang specifies which interpreter should be used to execute the script. Since we are working with Bash we will set this to /bin/bash.

At this point you can start writing your script, but there are a few additional things I like to add first:

set -e
set -u

These set options control the execution behavior of the script, and are optional, but I highly recommend using them. The -e option tells the script to fail on any instance where a command returns a non-zero exit code. This can make you script run in a more predictable manner. The -u option is useful for keeping your scripts clean. It will cause the script to fail if you declare a variable but never use it.

Finally we output a message to the screen using echo.

echo "Hello World"

The echo command will simple output whatever text is passed to it, for the most part it resembles the PowerShell Write-Host cmdlet. echo is the defacto way to output text to the console in most example you’ll find on the internet, but in the next post in the series we are going to discuss a more flexible option called printf. printf has a few more features that make it worth using in place of echo.

Executing the Script

To execute this script you’ll need to go to a Bash command prompt and type the following:

mark@atomo:~ >$ . ./hello_world.sh  

And that’s it! You should see “Hello World” echoed back to the console, and then you have been returned to a command prompt ready to execute somethign else.

Final Thoughts

Bash scripting can be a great skill to have when you start managing Linux systems. In this post we discussed options for setting up an environment to execute the example code, touched a little on the history of Bash, and ended with a simple example script to output “Hello World”. In the next post of this series we are going to discuss console output using echo and printf, strings, and variables.


Lets talk! Start a conversation about this post on Twitter