Terminal Tricks That Will Change Your Life

When I first started using the terminal for development it was a strange and awkward thing for me. I couldn’t stop thinking that having a GUI application to run the tasks I was trying to complete was superior and easier. Now, five years later, GUI apps get in my way more than help. GUI apps have become cumbersome to use while the terminal seems natural. If you’ve never used the terminal much in development or you’re just getting into it, here are some tricks I’ve learned that’ll change the way you do things forever.

This post is for developers with a casual acquaintance with the command line. CLI pros will be bored and complain that the title is misleading.

Intro to the terminal

Every Unix-like OS comes with a terminal Application. Windows users have to deal with PowerShell and cmd.exe unfortunately. The terminal is a simple window where you interact with your system by issuing text commands. There’s no clicking, just typing and pressing enter. Most people have no reason to open the terminal but developers should be comfortable using it on a day to day basis. If you haven’t “gotten into” the terminal yet, you should really give it a good college try. It’ll improve your productivity immensely and open up a world of new possibilities for what you might be able to do in your day to day work.

The terminal exposes a ton of commands, each of which have a corresponding binary installed somewhere on your system. The Unix philosophy for software revolves around the idea that an app should do one thing, only one thing, and it should do that well. For that reason, there are a ton of different single-use applications that you can use in combination to do some really cool stuff. This post will acquaint you with some of the tricks I’ve learned that helped me get more out of the terminal than I ever did before. If you’ve got just a passing familiarity with the terminal and want to level up, these tips should help.

Although I work on both Mac and Linux my examples will be run on a Mac. That shouldn’t matter for the most part however because there’s really not much difference between how the terminal applications and bash work on both platforms.

Tab completion

Let’s start with something easy. If you use bash (most people do by default) then you know that you don’t have to type in the full path or name of a command every time you want to use it, right? Well, you don’t. Instead, use tab completion. Here’s how it works:

  1. Begin typing the name of a command or a folder: cd my_p
  2. Press Tab a couple of times and you’ll be presented with some suggestions like this:
1
2
3
4
$ cd my_p # Here you press Tab
> my_profile my_pictures
$ cd my_pi # Press Tab again and bash will fill in the rest to...
$ cd my_pictures/

The example above is only an illustration. In reality, the suggestions will be shown below what you’re typing but the completion itself will happen on the same line as the one you’re typing on instantly if there’s an exact match.

If more than one file or command matches what you’re typing you’ll get suggestions. If you’ve typed enough that only one option could possibly be what you’re looking for then it’ll autocomplete it for you. This is useful when you only remember a part of a command name or have a very long file or folder name you need to type.

Create folders without worrying about parent folders

So you have a folder called images you downloaded and want to categorize its contents into sub folders. So you go ahead and create a pictures folder then a family, family/christmas folder for categories. What if I told you there was an easier way? Use mkdir’s -p option like this:

1
mkdir -p existing_folder/new_folder/new_subfolder

The -p option creates any parent directories that don’t exist. So that takes care of creating one folder within a subfolder that doesn’t exist but what about creating multiple files and folders in one go?

Creat multiple sibling files or folders in one shot

Suppose you want a directory structure like this:

1
2
3
4
5
6
7
8
9
root
  |
  - folder1
     |
     - subfolder1
     |
     - subfolder2
     |
     - another_subfolder

You’d probably create it like mkdir -p folder/subfolder1 then move on to create each sub folder individually. You don’t have to. Check this out:

1
2
mkdir -p folder1/{subfolder1,subfolder2,subfolder3,subfolder4}
touch folder1/subfolder1/{file1.txt,file2.md,file3.html}

The first command above creates a new folder with 4 subfolders that are sublings of each other below it. The second command creates 3 files inside of the folder1/subfolder1 directory.

Run a bunch of commands in one go

Sometimes you want to tell your system to do two things but don’t want to wait for the first one to quit. An example would be when you’re seting up a new front-end project. I use a lot of NPM packages and Bower resources in my projects. Whenever I clone a project on to a new computer I want to install all my dependencies from both resources in one go. So instead of installing all NPM packages then Bower components sequentially, I just run them at the same time.

The two operators you can use to achieve this are && (double ampersands) and ; (a semicolon). For example:

1
2
3
npm install && bower install
# or like this...
npm install; bower install

Both of those will run the npm install and bower install commands one after the other but there’s a slight difference between the way && and ; work. The && operator will only run the command that comes after it if the command before it succeeds. So, using the previous example, if your NPM dependencies failed to install for some reason then your Bower packages won’t be installed. It’s just like in programming where && means that both conditions must be true. On the other hand, if you use ; instead, then every command preceeded by a semicolon will be run regardless of its success or failure.

Examples of commands that should use &&

In a Rails app you’d want to make sure your database migrates before running a deploy task. When working with a git repository you probably want to make sure your commit takes with no merge conflicts or errors before pushing to a remote. So these would be typical commands:

1
2
3
rake db:migrate && rake db:seed && rake deploy # (You can run any number of commands at once, you're not limited to 2).

git add . && git commit -m "This should only be committed if my files were added" && git push origin master

Examples of commands that can use ;

I don’t think there are any commands that should use ;. I prefer && but there may be situations where you don’t care if a task fails and just want to move on to the next one.

1
sudo apt-get update; sudo apt-get upgrade

I like to upgrade regardless of what happens to my update sometimes. So sue me.

Drop into a newly created folder or git repo

How annoying is it to have to constantly type git clone https://github.com/billpatrianakos/Fractionless-Boilerplate.git && cd Fractionless-Boilerplate? Super annoying. So why not just do that all at once without having to even type the folder name. Here’s a few things you can do to create new folders either via git clone or a plain old mkdir to drop right into your new folder

1
2
3
4
5
# Clone a repository, rename it, and drop into its folder in one line
git clone https://github.com/user/really-long-repo-name.git short-name && cd $_

# Make a new directory and drop straight into it
mkdir my_new_folder && cd $_

$_ is a special bash variable that returns the last parameter passed to the previous command. So in the examples above, the last parameter was a folder name. That’s why running cd $_ dropped us into the new folders.

Create some aliases

When you first start using the command line its sort of fun to remember all the commands and some take pride in typing every last thing out but after a while it’ll become a pain and you’ll want to make things go a little quicker (I maintain that during development even typing every last command by hand is faster than point-and-clicking). Aliases are there to save you some typing.

For example, if you’re like me and you frequently list files in folders with permissions showing or need to show hidden files and folders then instead of having to type and remember ls -l or ls -la I set up ll and la instead.

Depending on your OS you may have a .bashrc or .bash_profile file in your home folder. I have both and one of them loads a special .bash_aliases file which by default doesn’t exist. Assuming that your Mac or Linux distro is set up to import an alias file when the shell starts (most of them are), you can create a new alias file in your home folder and load your shortcuts that way.

Create the file with touch ~/.bash_aliases then open it with your favorite editor (mine’s Nano) nano ~/.bash_aliases. Once in the file add some aliases like this:

1
2
3
# File listing shortcuts
alias ll='ls -l'
alias la='ls -la'

In addition to stupid little shortcuts like that, I have some time-saving scripts that I use to do things like generate strong passwords and connect to my servers via SSH. I hold those files in a folder called .bill in my home folder. Rather than having to type the path to those scripts every time I need to run one of those tasks, I set up an alias for it instead.

Bonus: Random password generator and SSH connector

The scripts I have aren’t worth the time to turn into something like a Ruby gem or NPM package but they’re also too large to be typed manually. So instead I add a few lines to my bash aliases to run them from anywhere. Super helpful when developing. Like I mentioned before two of my favorites generate random passwords and connect me to any one of my servers via SSH without me having to remember the IP address.

If you want to use any of these scripts follow the instructions below. Once they’re saved somewhere safe on your system add an entry to your .bash_aliases file to call them from anywhere.

The SSH connecting script

Copy and paste the code from that Gist into a file called anything you like and save it somewhere on your system. I recommend created a special folder for little scripts like this in your home folder. If you prepend a dot to the name it’ll be hidden like my .bill/ folder.

Once the code is saved to that file, cd to the folder you saved it and make it executable with chmod +x name_you_gave_the_script.

The way the SSH script works is you fill in the example hash with a nickname and the IP address of any servers you SSH into frequently then call it by its alias to connect. For me, I type connect myserver and I’m in. No more ssh me@123.456.7.8 or having to remember IP addresses. Yes, you can go by domain name but that feels dirty and I like a record of my IPs around anyway.

To have the script available from anywhere, add this line to your .bash_aliases file:

alias connect='/path/to/script'

If you get an error trying to run your new alias it’s because you need to reload your dotfiles or open a new terminal window/tab. Run source ~/.bashrc && source ~/.bash_profile to reload them and get the aliases to take effect.

Random Password Generator

This script will generate a strong password based on the input you give it. You can choose a quick random string, specify the length of the string, specify whether special characters are included or whether only alphanumeric characters are used, or get a crazy long Fort Knock password.

Note: You’ll need Rubygems and the Trollop gem installed on your system to run this script (gem install trollop). Pass -h to the script to get help text.

The same rules apply to this script as the SSH connection script. Save it, make it executable, create an alias for it, and run it.

So that’s all I have for now. If you’ve been using the terminal for a while then these aren’t exactly life changing but for someone new, they’ll certainly make a difference in productivity when at some point your journey through command line land.

Server administration, Tips

« Should I Load Google Web Fonts JS API or the CSS Link? What's the difference between jQuery's document.ready() and window.load()? »

Comments