I <3 bin/bash - An Introduction
For anyone looking to get started in software development or operations as it is pretty much a requirement that no matter whether you favor Windows, Mac, or Linux that you'll need to forge an intimately familiar relationship with a Unix style terminal.
quinn@FingerSkilletII $ i <3 bin/bash
-bash: 3: No such file or directory
Your terminal, or shell as it is also called, may or may not love you back. It all depends on how much time and effort you are willing to put into it, like any other relationship :)
This is the first of a series of blog posts that are going to help you feel more comfortable in a Unix-style shell. By the time you are through, and with practice and time, you'll be able to comfortably navigate around in a Unix terminal. Awesome, right?
Setting up your terminal
Windows Users
Since Windows isn't a Unix based operating system, the fastest way to start playing around with Unix commands on your Windows machine is to install Git BASH for Windows. If you're unfamiliar with git and/or version control: don't worry about that right now. While it is a topic you'll need to familiarize yourself with later and you will need to know how to use git at some point, for the purposes of going through these exercises you'll just be making use of the Unix style commands that they ported for Windows.*
Mac Users
macOS is a Unix based OS, so for the purposes of this tutorial you already have almost all the commands you need!*
Optional (but strongly encouraged): install Homebrew.
Why Homebrew? Basically, it allows you to quickly download command line tools via brew install and easily keep them updated via brew update which is a huge benefit. Most, if not all, of the tools you can install via brew can be downloaded and installed manually, but when you go to update them you will have to go through the same process every time for each one. After a while it can be hard to keep track of what you've downloaded and what needs updating, so it's very easy to let things get out of date. brew update will search for updates for anything you've installed with brew, so in that regard keeping things updated is super-easy.
There are a few Unix based commands that I'll touch on over the course of the tutorial that do not come by default with macOS, so please install the following:
brew install wget tree ack
Linux Users
Linux is also Unix based and you already have a package manager built-in, probably either yum or apt-get, so you're pretty much set. If you don't have tree or ack installed, please install those now using the command that matches your system:
sudo yum install tree ack
sudo apt-get install tree ack
Although most distributions of Linux just install with either of the above, if neither of the commands above work for you please take a look here for how to install ack on your distribution.
* Non-Linux users: there is also the option of setting up a Linux environment on your machine with with what's called Vagrant. I'm not recommending that here because 1) that's a whole different set of tutorials and 2) one purpose of this tutorial is to help you learn how to use your command line environment in a relatively standard way.
Who and What: Users
The first and possibly easiest thing to understand about your system is that it has users. Typically there is an admin account and one or more user accounts, e.g. jaynec. On Unix based systems it is important to know that there is also a root user that is basically a "super administrator".
- Upside: you can do literally anything as the root user.
- Downside: there is no guarantee that you will necessarily be prompted even if you are about to do something with serious consequences.
The way to run commands as root is sudo <cmd>, for example:
quinn@FingerSkilletII $ whoami
quinn
quinn@FingerSkilletII $ sudo whoami
Password:
root
You can see that when I tried to run the same command as root I was prompted for my user password and that my user showed as root rather than quinn.
Now that you know a little about who root is, it's worth taking a look at my prompt. You can see that before the whoami command there's quinn@FingerSkilletII $. quinn is my username and FingerSkilletII is what is called the hostname, which for all intents and purposes can be thought of as the computer's name. The $ is the default way to end a prompt, although if you were to switch users to the root user (as in actually logging in as root and not just using sudo <cmd>), then the $ would change to a # by default. This is important to notice when reading the commands and terminal output that people paste online. To switch to another user:
quinn@FingerSkilletII $ sudo su work
work@FingerSkilletII $
Depending on your system you may be able to run the su command not as root. To log out of this session, hit cmd+D (or ctrl+D for Windows users). To log in as root you use the same command without supplying the username:
quinn@FingerSkilletII $ sudo su
root@FingerSkilletII #
Note that in order to switch users to root you will need to run su with sudo.
Back to whoami - did you take a moment to research the command before running it? If not, this is the perfect time to start learning that habit.
For practice, rather than taking my (or the internet's) word for what commands do, we'll be using the command's manual:
quinn@FingerSkilletII $ man whoami
WHOAMI(1) BSD General Commands Manual WHOAMI(1)
NAME
whoami -- display effective user id
...
To scroll use your arrow keys or spacebar. When you're done, hit q to quit.
As you get more familiar with the commands available to you, you might find that you need to reference the manual less and less. No matter what though, you should always take a moment to analyze what a command is doing before you run it - especially if you're going to be running it as root (sudo <cmd>).
You can also find manual entries of other commands that reference the command you are running. Try running man -k whoami to take a look at what commands reference whoami.
Review
- User accounts vs
root, the "superadmin" account whoami: how to figure out what user you are logged in asman <cmd>: access the manual for a specific command- use
qto quit - use arrow keys or your spacebar to scroll
- use
-kto find manual entries that contain the command you provide sudo <cmd>: run a command withrootprivilegesless: spoiler, to be revealed when we cover text files. Though you couldmanfor it ;)
Directories
On a system there are directories (or folders) that contain files. To get started, let's make a few directories and view their contents:
quinn@FingerSkilletII $ mkdir astro
quinn@FingerSkilletII $ mkdir astro/astronomy
quinn@FingerSkilletII $ mkdir astro/astrophysics
quinn@FingerSkilletII $ ls
astro
quinn@FingerSkilletII $ cd astro/
quinn@FingerSkilletII $ ls
astronomy astrophysics
To review: we made the astro directory as well as its subdirectories astronomy and astrophysics. To list the contents of the astro directory we used the ls command and we were able to change directories with cd. Notice that ls <directory> gives you the contents of the directory <directory>, but ls with no directory gives you the contents of your current working directory.
Not sure where your current working directory is? Have no fear! You can find out with the pwd command, which stands for print working directory (print like "print to screen" rather than "print to printer"):
quinn@FingerSkilletII $ pwd
/Users/quinn/blog_post/astro
The pwd command outputs the full path or absolute path, which of relevance right now includes /Users/quinn. ~ is shorthand on Unix systems for your home directory, so if you ever want to change directories to your home directory or one of its subdirectories you can use cd ~ or cd ~/<rest>/<of>/<path. This is called a relative path.
A relative path isn't just restricted to your home directory: it's whenever you base a directory's location on another directory. An example of this is when you describe your neighbor's flat/apartment: you could say "it's the apartment next to mine" (relative) or "its address is 221B Baker Street" (absolute).
Besides using your home directory, there are other ways of making a relative path. Try running this:
quinn@FingerSkilletII $ cd ..
That command moved you "up" one directory relative to your current directory. You should now be in the ~/blog_post directory (or your equivalent). To play around with this a little bit, change directories into astro/astrophysics and:
quinn@FingerSkilletII $ pwd
/Users/quinn/blog_post/astro/astrophysics
quinn@FingerSkilletII $ cd ../../
quinn@FingerSkilletII $ pwd
/Users/quinn/blog_post
quinn@FingerSkilletII $ cd -
quinn@FingerSkilletII $ pwd
/Users/quinn/blog_post/astro/astrophysics
As you can see, you can stack the .. to go up as many directories as you like. Since the full path of astrophysics has 4 parent directories, I can nest .. up to 4 times in this case. I used cd - to return to my last location, which in this case was just to go back into astro/astrophysics.
Moving on, if you wanted to create and view a parent directory and its subdirectories you don't need to cd into the directory to do so. Check this out:
quinn@FingerSkilletII $ mkdir -p astro/astronomy
quinn@FingerSkilletII $ mkdir -p astro/astrophysics
quinn@FingerSkilletII $ tree
.
└── astro
├── astronomy
└── astrophysics
3 directories, 0 files
A lot faster to get to the same point, yeah? So to review, the -p flag tells mkdir to create the parent directory if it doesn't exist. To see what happens without the flag when it doesn't exist, try running mkdir newdir/subdir and see what happens :)
The tree command prints out all subdirectories and their contents - so if there were files here they'd display as well. tree can be superuseful but take care: the output may spike your blood pressure if you run it in a directory with a lot of subdirectories and files.
Now to clean up: to delete an empty directory you can use rmdir, but if you have items in your directory as we now do you'll need to recursively remove them with rm -r. We'll see this command again in the next post about files, but for now:
quinn@FingerSkilletII $ rmdir astro/astronomy
quinn@FingerSkilletII $ rm -r astro
What just happened: rmdir astro/astronomy deleted the empty directory astronomy, but rm -r astro deleted astro and all it's subdirectories and contained files. In this case, that was only the empty subdirectory astrophysics.
Review
mkdir: make a directory- use
-pto create a parent with its subdirectories ls: list the contents of a directorycd: change directories- What does
cd ~do? - What does
cd ../..do? - What does
cd -do? pwd: basically, "whereami" or print working directorytree: prints a directory and its subdirectories- What does
tree ~do?
--> Protip: figure out what the command does before you run it. Author is not responsible for command output that overtakes your terminal(/) (°,,°) (/) rmdir: remove an empty directoryrm -r: recursively remove a directory and its contents
Level-up
Did you know that you can use your tab key to autocomplete directory (and file) names? Give it a try! Note that it can only complete what is unique, so if you enter ast and have astronomy and astrophysics directories, it'll complete to astro, but if you enter astron tab will complete to astronomy.
Review
So we've covered a lot in this post. When you're ready, please hop into the next post on how to use files (link forthcoming).
Convenient Command List
whoami: how to figure out what user you are logged in asman <cmd>: access the manual for a specific command- use
qto quit - use arrow keys or your spacebar to scroll
- use
-kto find manual entries that reference sudo <cmd>: run a command withrootprivilegesless: spoiler. maybe tryman less?mkdir: make a directory- use
-pto create a parent before its subdirectories ls: list the contents of a directorycd: change directoriespwd: basically, "whereami" or print working directorytree: prints a directory and its subdirectoriesrmdir: remove an empty directoryrm -r: recursively remove a directory and its contents- Use tab to autocomplete the name of a file or directory.
And now you've definitely earned a:
Keep practicing!