Creating basic shell scripts

How to wrap your code into a file and run it from the command-line

When we start to learn the command-line interface, we generally learn and explore it interactively. That is, we enter one command at a time so that we can see the results of each command.

Here is a GIF of me using the command line to explore a directory of Shakespearean plays, counting the number of words and the number of times the word "murder" appears, both in King Lear and in all of Shakespeare's plays:


Using the command-line interface in this interactive fashion is fine, when trying things out. However, as you've likely noticed, typing is a very error-prone activity. So for complex tasks that we want to repeat, the best practice is not to retype their code from the beginning, but to create a self-contained shell script that can be run as a one-liner.

Our first shell script

Let's start off with something easy. Make a junk directory somewhere, such as /tmp/my-playground and change into it – we don't need to litter our actual workspace with test code.

A shell script is nothing more than a text file, which should make sense, as all of our command-line scripting has so far been, well, text.

Let's use the nano text editor to create a shell script named Follow these steps:

  1. Run nano
  2. nano should open up and present an empty file for you to work in. Type in the shell command:

     echo "Hello world"
  3. Then press Ctrl-X on your keyboard to Exit nano
  4. nano will ask you if you want to save the modified file. Hit the y key (for "yes").
  5. nano will then confirm if you want to save to the file named Hit Enter to confirm this.
  6. Run the script with this command:


Here's what the steps look like as a GIF:


So is not very impressive, but it captures the gist of what we want to do: wrap up a series of commands into a file, i.e. a script, so that we can re-run that script as much as we'd like.

We not only eliminate the prospect of typographic errors that occur when retyping commands, we also open up the door to making the script reusable in different contexts.

A re-usable shell script with arguments

Let's make more complicated. Instead of just echoing Hello world, let's design the script so that it will say Hello to a specific value (i.e. someone's name). And we'll make the script sound more excited.

Here's the proposed usage:

bash Dan

And here's a GIF:


First of all, how do we customize echo "Hello world"? By replacing world with a variable. Let's try it interactively from the command-line:

echo "Hello $yourname"


Hello Dan

So the question is: how do we get the script to read in the argument (in this case, someone's name) that we pass into it?

bash George

We do this via a special variable in bash. The variables, $1, $2, $3 (and so on), refer to the first, second, and third arguments that were passed into the script from the command line.

Thus, in the above example, George will be stored in the variable $1 when begins running.

So reopen with nano and change the code to this:

echo "Hello $yourname"

Save the changes and run bash Mary to see how the output changes.

Want to return the output in all caps? Then modify like so, piping the output through tr to replace lowercase letters with uppercase letters:

echo "Hello $yourname" | tr '[[:lower:]]' '[[:upper:]]'

And if you want to be concise, you've probably noticed that the variable, $yourname, isn't really needed. The code could be simplified to this:

echo "Hello $1" | tr '[[:lower:]]' '[[:upper:]]'


Time to slow down. If you can make a script that you can execute like this:


Then you have already learn a major concept. At the very least, you have learned the method by which programmers stuff a bunch of complicated into a "container" that anyone else can run in a single line.

In the next tutorial in this series, I've taken this same idea except to go more indepth in making a script "reusable". Do you need to make a reusable script, right now? Do you even know what "reusable" means? If not, then you don't need to read that tutorial, just yet.