How to Use the Terminal App for Shell Scripting on macOS
Dial in your shell scripting fundamentals for Mac with this helpful overview.
The Terminal application that ships with macOS is a powerful tool for controlling your Mac. But oftentimes less experienced users are reluctant to click into that powerful black box on their Mac monitor for fear of getting in over their heads and accidentally breaking something. Today, we’ll go over some basic information to get new Terminal app users started on the right foot.
First, we’ll take a look at how to execute some simple Unix commands from the Terminal directly, and then we’ll extend that understanding to allow you to link multiple Unix commands together in a text file generally referred to as a shell script.
These files are called shell scripts because they are comprised of a series of commands that are executed in something called a shell (that is powering the Terminal app). While there are a number of different varieties of shells that you may use on Mac, such as
sh and others, the default shell on Mac is
The differences between these various shells are obscure enough to largely gloss over here in this blog, but it is worth noting that each variety of shell reads its own set of environment definition scripts at machine startup and user login respectively. So, when you graduate to automating the execution of shell scripts in the Terminal, the shell type will become a more relevant consideration.
Understanding the Shell Environment
When you open the Terminal app, you’ll be met with a blank screen. But there is already information stored in this “environment” you’ve created and entered – in the form of environment variables – just by your having started the app. These variables are accessible from anywhere within the shell environment. This means that either a human user or a scripted process can access these bits of information as needed either directly from within the Terminal, or from a script that is called from the Terminal.
As an example, suppose you have a script that needs to connect to a third-party service like a database. You may elect to set a username and password for the database as environment variables for the script to read, so it doesn’t need to have sensitive information “hard-coded” into it.
To print the currently defined environment variables, you can type the following into the Terminal:
To set an environment variable for the first time, or to overwrite an existing variable, you can simply run:
To access an environment variable, you can type a $ and then the variable name, like so:
Notice there is a standard format for writing environment variable names. It is not strictly required, but it is standard practice to name your environment variables in
Navigating the File System
In order to tell your Mac where a file is, you’ll need to be able to navigate the file system. To do so, we can use the change directory (cd) and list files (ls) commands. In the code block below, each line that begins with a $ represents user input, and the subsequent line (if there is one) is output being printed to the Terminal.
$ cd example
$ cd ..
First, we list the files and directories in our current directory by running
ls. We see that there is a file called
example.txt and a directory called example. We then
cd into the
example directory, and run
ls again. There, we find a second file called
cd back up one "level" in the file system by running
cd .., which puts us back in the directory where we started. Finally, we confirm that we are, in fact, back where we started by running
ls one last time.
We can also change to any directory we have the file path for and then return to the home directory, like so:
Key Unix Commands to Know
cd – Change directory
ls – List contents of a directory
cat – Read the contents of a file
cp – Copy a file or directory
cp /example_directory/example.txt /second_example_directory/example.txt
mv – Move a file or directory (or rename it)
mv /example_directory/example.txt /example_directory/example-v2.txt
grep – Filter text (and -l list the matching results)
grep -l "these exact characters" example.txt
Piping output from one command to the next
One of the most powerful aspects of shell scripting is the ability for users to “pipe” output from one command to the next with the
For example, list only files that contain “example” in the filename:
ls | grep -l example
Writing and running a simple shell script in the Terminal app on macOS
A shell script can be as simple as a list of commands like we looked at above to be carried out in sequence. You’ll want to tell the shell explicitly what interpreter should read the code with a standard first line called a “shebang.”
mkdir example_output && cd example_output
echo "Hello World" >> example.txt
You can run the above example by pasting that text into a text file called
example.sh. You’ll then need to navigate to the file’s location in the Terminal and run:
chmod +x example.sh # only needs to be run the first time
rm -rf example_output # get rid of any old examples if they exist
You should see the output:
First learning to use the Terminal app on macOS can be intimidating. But as we’ve shown above, it is pretty straightforward, and you will level up big time as a Mac user or admin when you begin to access resources and automate processes in this way.