Making the Shell Less Scary - Starting out
Tags: beginners, cli
Published: 2019-04-01 20:10:50

---
title: Making the Shell Less Scary - Starting out
published: true
tags: beginners, cli
canonical_url: https://www.ballpointcarrot.net/posts/shell-less-scary-first-commands/
---

I will fully admit that I grew up comfortable working on a computer without a GUI. From my early days, I had an old computer that I mainly used to play games (some things never change, but current ones don't come on 5 1/4" floppies); in order to get those games to run, I learned from my Mom how to access the correct drive, and the commands to run in order to start up the game.

Today, even though we have fancy GUI apps to do a lot of the work that we need to get done on a daily basis, I still find that it's easier for me to quickly open a terminal window, enter a few commands, and complete whatever task I was doing. Not everything benefits from this approach (imagine doing image editing with a text editor!), but tasks involving finding files, moving files around the system, and working on remote systems works are things that I would much prefer a terminal for.

Today I'm going to dive into a few of the commands that do just the things that I was talking about. These are some of the commands that you would end up using on  a day-to-day basis in a terminal window; hopefully I can shine some light on some corners of them that you don't expect.

### Directories and Files

Let's say you're an avid photographer - you'll have a lot of photos collected. In order to make sense of your collection, you're going to want to organize those photos. If they were physical photos, you'd want to collect them by the event that you took them at:

* Tim's birthday party
* Joe's wedding
* Vacation photos from Las Vegas
* random photos of food
* far too many cat pictures
* etc.

Additionally, let's say these photos happened over the course of a few years.

Borrowing from the physical realm, we can place these photos into different folders, or *directories*, in order to keep them organized. Let's lay them out like so:

* 2018
  * Joe's Wedding
  * I &lt;3 Food
  * My Cat
* 2019
  * Tim's Bday Bash
  * Vegas trip
  * My Cat
  * I &lt;3 Food

You'll notice there are duplicate names here - that's okay, because they're nested within two different folders.

Now, all of these folder names are legit as they stand, but they'll be a little harder to deal with when on the command line with some of the special characters and spaces. It's a standard convention to replace spaces and special characters in names to make it easy to deal with, while retaining most of the meaning that was present in the original names; most of the replacements are things like dashes or underscores. This would be my likely replacement:

* 2018
  * joe-wedding
  * i-heart-food
  * my-cat
* 2019
  * tim-bday-bash
  * vegas-trip
  * my-cat
  * i-heart-food

Syntactically very similar, and much easier to deal with while typing.

So rather than pulling up a file manager window, let's make this structure out of commands at a terminal.

#### `mkdir` makes the dirs

the `mkdir` command is used to make a directory. The basic invocation is very straightforward:

```plain
$ mkdir <folder-name>
```

This command will create a new directory with the given name based on the directory you're currently in (referred to as your 'Current Working Directory' or 'Present Working Directory'). Sometimes the terminal you're using will tell you where you are as part of the prompt; even if not, you can find out by running the command `pwd` to give you that directory.

```plain
$ pwd
/home/ballpointcarrot
```

So let's make our photo collection structure:

```
$ mkdir 2018

```

Wait... Nothing came back. Did it do anything?

#### add `ls` to the list

`ls` is a versatile command - it gives you a listing of your PWD. This becomes handy when you're looking around you filesystem, and generally know where something is located. If we do an `ls` where we are now, you'll see something like:

```plain
$ ls
2018/   Desktop/        Downloads/      Notes/          Videos/
Books/  Documents/      Music/          Photos/
```

Oops... that 2018 isn't in the right spot. Let's move it with `mv`:

```plain
$ mv 2018 Photos

```

Again, we get no output signifying anything. However, on the next `ls`:

```plain
$ ls
Books/          Documents/      Music/  Photos/
Desktop/        Downloads/      Notes/  Videos/
```

Now we can see that the 2018 folder is no longer here. We want to make sure that it's in the Photos directory though, so we'll check there, too:

> Note: this shows that the `ls` command can be used on folders - meaning you don't have to be *in* the folder to use `ls`. That gets handy when you're searching a lot of subfolders.

```plain
$ ls Photos
10262018_0001.JPG  10262018_0035.JPG  10262018_0069.JPG  10262018_0103.JPG  10262018_0137.JPG  10262018_0171.JPG  10262018_0205.JPG  10262018_0239.JPG  10262018_0273.JPG  10262018_0307.JPG
10262018_0002.JPG  10262018_0036.JPG  10262018_0070.JPG  10262018_0104.JPG  10262018_0138.JPG  10262018_0172.JPG  10262018_0206.JPG  10262018_0240.JPG  10262018_0274.JPG  10262018_0308.JPG
10262018_0003.JPG  10262018_0037.JPG  10262018_0071.JPG  10262018_0105.JPG  10262018_0139.JPG  10262018_0173.JPG  10262018_0207.JPG  10262018_0241.JPG  10262018_0275.JPG  10262018_0309.JPG
10262018_0004.JPG  10262018_0038.JPG  10262018_0072.JPG  10262018_0106.JPG  10262018_0140.JPG  10262018_0174.JPG  10262018_0208.JPG  10262018_0242.JPG  10262018_0276.JPG  10262018_0310.JPG
...
```

Whoa! Where's the 2018 folder? These are all just JPG files (the photos that I've been dumping without organizing into the Photos folder). Fortunately, I can filter out the type of object returned from `ls`:

```plain
$ ls -d */
2018//
```

There's our folder. Now let's explain that command: the `-d` within the command tells `ls` that we just want directories, and not files. However, `ls` isn't smart enough on its own to just grab the directories on its own; we have to explicitly say grab "all directories", which is where `*/` comes in - it signifies "anything in the current directory" with the asterisk (also called a star or wildcard), and the forward slash is for anything designated a folder.

Let's get to work on the rest of those folders. First, let's put ourselves in the right place.

#### `cd` - not just for music

The `cd` command changes our current working directory. By changing directories, it gives us the ability to change context with what we're doing on the filesystem. In our case, we'll change to the Photos directory, because we're working in the context of organizing our Photos. Makes sense.

```plain
$ cd Photos

```
Again, the command has now output, but we can do a `pwd` and see that we've changed places:

```plain
$ pwd
/home/ballpointcarrot/Photos
```

Now let's finish up our 2018 folders. Me, being lazy, want to do everything in one shot - fortunately, `mkdir` lets us do just that:

```plain
$ mkdir 2018/joe-wedding 2018/i-heart-food 2018/my-cat
```

This creates three folders, all nested neatly under the 2018 folder. "Great!", we say, and we go to do 2019:

```plain
$ mkdir 2019/tim-bday-bash 2019/vegas-trip 2019/my-cat 2019/i-heart-food
mkdir: cannot create directory ‘2019/tim-bday-bash’: No such file or directory
mkdir: cannot create directory ‘2019/vegas-trip’: No such file or directory
mkdir: cannot create directory ‘2019/my-cat’: No such file or directory
mkdir: cannot create directory ‘2019/i-heart-food’: No such file or directory
```

Uh oh... because we never created the parent 2019 folder, it's not allowing us to build the rest of the directories. We can outwit it though; `mkdir` has a parameter option `-p`, which gives us the ability to make parent directories within the same call:


```plain
$ mkdir -p 2019/tim-bday-bash 2019/vegas-trip 2019/my-cat 2019/i-heart-food

```

All good. Just to double-check:

```plain
$ ls 2019
tim-bday-bash/  vegas-trip/     my-cat/         i-heart-food/
```

### Moving the files in

So now we've got our directory structure in the Photos directory, with a boatload of random JPG files. How are we going to get them organized? It looks like a lot of them are around the same dates (look at all the 10262018_xxxx files we have up there). Let's take a look at one or two of them to get a sample, to make sure it's the right event. 

> Note: This step will be different depending on the platform you're on, so I'll give both.

```sh
# OSX example
$ open 10262018_0001.JPG

# Linux example
$ xdg-open 10262018_0001.JPG
```

Both of these commands do the same thing - they ask the current environment to figure out who the best person to open a JPG file is, and then executes that program. Ideally, you'll see a window with your picture loaded.

![miles](https://www.ballpointcarrot.net/images/miles.jpg)

Oh look, it's a cat photo. We know where those are supposed to go. I'm going to assume the 300+ photos around this time period are all cat photos (don't judge). We're going go go back to using the `mv` command. However, instead of individually moving the files one-by-one (which would take *forever*), we'll make use of our friend the wildcard, and make all of the files move on their own:

```plain
$ mv 10262018_* 2018/my-cat

```
Again, we get nothing back as output, so let's double-check:

```plain
$ ls 2018/my-cat
10262018_0001.JPG  10262018_0035.JPG  10262018_0069.JPG  10262018_0103.JPG  10262018_0137.JPG  10262018_0171.JPG  10262018_0205.JPG  10262018_0239.JPG  10262018_0273.JPG  10262018_0307.JPG
10262018_0002.JPG  10262018_0036.JPG  10262018_0070.JPG  10262018_0104.JPG  10262018_0138.JPG  10262018_0172.JPG  10262018_0206.JPG  10262018_0240.JPG  10262018_0274.JPG  10262018_0308.JPG
10262018_0003.JPG  10262018_0037.JPG  10262018_0071.JPG  10262018_0105.JPG  10262018_0139.JPG  10262018_0173.JPG  10262018_0207.JPG  10262018_0241.JPG  10262018_0275.JPG  10262018_0309.JPG
10262018_0004.JPG  10262018_0038.JPG  10262018_0072.JPG  10262018_0106.JPG  10262018_0140.JPG  10262018_0174.JPG  10262018_0208.JPG  10262018_0242.JPG  10262018_0276.JPG  10262018_0310.JPG
...
```

Great - all our cat photos are now pleasantly sorted.

I'll leave us here for now. I want to make this a continuing series of posts, so please let me know if there's a command that you're interested in. I know that this one may be a little too basic for a lot of dev-types, but hey - everyone has to start somewhere, right? As long as someone makes use of it, I'm happy.