At one point (fairly recently), I didn't have a want/need for any scripting or automation in my life. I was content doing everything by hand, or in the case of shell scripts - I didn't realize just how useful they could be in my day-to-day computing life. Boy, was I missing out. Writing small/quick scripts to accomplish repetitive tasks is the best thing ever. They aren't just a time-saver, they actually make your work more efficient. Delegating scripts to do tasks that you would usually do manually isn't as hard as it initially seems. In fact, you probably already have useful time-saving scripts that you use now, as there are a lot them already built into modern OSs.

For instance, as a Mac user - back in the day there was a utility that was a must-have: A Better Finder Rename. This application has been around since about 2009, and it does a great job at what it does - batch rename files. There are plenty of other utilities out there that were similar. Some, like ABFRN are still around, while others - like File Buddy, didn't fare so well.

And guess what? At some point, Apple decided that a batch rename function was swell and should be baked into the OS. They released it to the masses in Mac OS High Sierra (10.13) as a contextual menu item, much like the normal Duplicate and Compress items that already lived in the menu. Comparable to a script that you could write to do a simple task, the OS file/folder rename function just works. Sure, it's a little tricky to use until you grasp the basics, but you can do most simple rename tasks right from your contextual menu and move on with your life. So, rather than shelling out your hard-earned dollars for a full-fledged application, you can just use the tools already provided to you.

Writing your own scripts is like that. Sure, you could do things the hard way (manually), which can be tedious and slow... or you could automate your process(es) and be quick and done.

This is part two in the multi-part series "This is gross.sh."
If you're feeling lost or want some background on what this article is about, be sure to read part one.

Doing the thing

So, that said - we're going to build a basic shell script, and then make it a little less ugly. If you're a Mac/Linux user, you'll have a lot of the things needed to start already built into your system. If you're a Windows user, you have to set up a few things to get started. See Ryan's post on setting up a dev environment on a Windows machine and grab CMDr to get up and running quickly. Here's a list of things that you should have to get going on any platform: (I have listed several options, but you should pick the one that works best for you)

A terminal emulator for accessing CLI tools:

  • Terminal.app (macOS) - built into macOS. Easy and free. (macOS Catalina (10.15) uses the zsh shell by default now, btw)
  • iTerm 2 (macOS) - in my opinion, the best terminal emulator. This is what I use most of the time.
  • Hyper (Windows/macOS/Linux) - Electron-based terminal build on HTML/CSS/JS
  • Kitty (macOS/Linux) - GPU-based terminal emulator
  • CMDr (Windows) - Portable console emulator for Windows. Ships with a Monokai theme and a custom prompt already. Yay!
  • Terminus (Windows/macOS/Linux) - highly configurable terminal emulator for Windows, macOS and Linux.

A text editor or IDE capable of writing and saving to plain-text files:

(These are by no means an exhaustive list. There are lots of other options out there. Let me know what you like to use that isn't up there!)


For the sake of these exercises, I'll be making a simple Bash script and then adding some basic styles to it. We'll be adding some user input and the ability to create a new file (if it doesn't already exist).

For those new at this, a Bash script is not the same thing as using the Bash shell. A Bash script is just a shell script that uses the Bash scripting language. For a better explanation of the difference in the sh/bash shell and sh/bash scripts, see this post comment.

We'll be working on the command line (on a Mac) and saving files on our local desktop directory. If you're using Linux/Windows, you'll have different paths that need to populate. For the sake of this article, navigate to your Desktop folder on the command line with cd ~/Desktop. You can use a text editor if you'd like, but make sure you're working in plain text.

Building the basics

Let's start with writing a simple shell script that will make an empty file.

Open up your text editor, create a new file and then go ahead and save it on your Desktop as myscript.sh.

Inside of that new file that you just created, copy/paste the following code into your new document:

#!/usr/bin/env bash

touch mynewfile.txt

Go ahead and save and close your file.

Making your document a script

Right now, your document is a plain, boring document. You need to flag your file as an "executable", which just lets your OS know that the file should be run as a script. In order to make your script executable, you need to open up your terminal emulator and navigate to your Desktop with cd ~/Desktop. Next, we'll run chmod on the document and set the magic bits so we can run it as a script:

chmod +x myscript.sh

Guess what? You just made your first script.

Running the thing

Now that you have a real script, let's test it out. Run your script by typing the following (or copy/paste/enter) in your terminal:

./myscript.sh

You should now see a new file on your desktop called mynewfile.txt that we just created with a one line script. Crazy!

What is this black magic anyway?

So, your new cool script consists of two distinct parts. While simple, those two lines are doing important tasks.

The first line is what's called the shebang (Yeah, HAR HAR. I know.)

#!/usr/bin/env bash

This line is the first line that should appear in your script. It tells your terminal environment which interpreter you want to use to read and perform the actions in your script. In this case, we're using the bash interpreter specified in /usr/bin/env.

The second line is the command that gets executed when you run the script. In our script, we're using the command line tool touch which is opening up a new file with our specified filename of mynewfile.txt and saving/closing the file immediately. Essentially, we just created a new, empty file with our specified name via a script.

Note that I'm using #!/usr/bin/env bash instead of #!/bin/bash. The decision to run your script using whichever shebang format you'd like is entirely yours. Here's why I do it this way. YMMV.

Wrapping it up

You've now officially written your first script! It may not look like much, but this simple script is the building block for learning how to write more robust scripts to perform much more complicated tasks. In the part three, we'll be discussing how to use variables, echoes, and functions.

This is gross.sh

  • Part One - Introduction
  • Part Two - Getting started with script automation
  • Part Three - Variables, Echoes, and Functions... oh my!