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.
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.
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.
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.
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
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.
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.
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.
No programming discussion is complete without the famous "Hello World" example. In this script we are introducing the "shebang" (
#!), set options, and the
#!/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.
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:
#! 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
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
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 "Hello World"
echo command will simple output whatever text is passed to it, for the most part it resembles the PowerShell
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 has a few more features that make it worth using in place of
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.
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
printf, strings, and variables.