Monday, January 11, 2016

7 tips & tricks to get you started on the Unix command line

In a world where people are used to interact with technology by sliding their thumbs over shiny buttons, the command line often seems like an archaic way of interacting with an OS. Surely the Unix shell is supposed to help you quickly interact with the file system or automate mundane tasks–but don't you need a neckbeard to understand all this stuff anyway?

You'd be surprised to find that even for clean-shaven people the learning curve is not that steep. Ever found yourself stabbing the Up key hundreds of times because you can't find that command you typed in a couple of minutes ago? Can't remember the syntax to unarchive that darn .tar file? No clue why Ctrl+C and Ctrl+V won't work? Don't worry, ask a Swiss! All you need is a short list of tips and tricks and you'll find yourself saving lots of time on the command line. No uncontrolled hair growth required.


1. Know your history

The days of stabbing the Up key hundreds of times are over! There are much easier ways to bring up commands from your history. Most of them are listed in the man pages of history. A few useful examples are:

$ !!        # re-run the previous command
$ sudo !!   # re-run the previous command as root
$ !-N       # re-run the N-th most recent command
$ !string   # re-run the most recent command that begins with string
$ !?string? # re-run the most recent command that contains string

You can also re-run the N-th command from your history:

$ history
 2181 ls
 2182 cd -
 2183 man ascii

$ !2182
cd -
/home/guest/Desktop

You can also add arguments from previous commands to your current command:

$ !:1    # get the first argument of last command
$ !:2-3  # get the second and third arguments of last command
$ !:^    # another way of getting the first argument
$ !:$    # get the last argument

Alternatively, you can use the Page up and Page down keys to search the history by uncommenting the following lines in /etc/inputrc:

# alternate mappings for "page up" and "page down" to search the history
# "\e[5~": history-search-backward
# "\e[6~": history-search-forward

2. Know your hotkeys

If there are some tasks that you perform multiple times a day, saving even a split-second of time can greatly pay off over time. Thus a lot of time can be saved by familiarizing yourself with some comment hotkeys.

The absolute basics:

  • Ctrl+Alt+T: Open a new terminal.
  • Home and End: Move the cursor to the beginning or end of the current line.
  • Tab: Autocomplete a line of text.
  • Ctrl+Shift+T: Open a new tab in the gnome terminal.
  • Ctr+Left, Ctrl+Right: Jump between arguments in the current command. Note that on Mac OS X, this shortcut is Esc+B and Esc+F instead.

Slightly more advanced, but nonetheless handy for everyday use:

  • Ctrl+U: Cut the current line
  • Ctrl+Y: Paste a line cut with Ctrl+U
  • Ctrl+L: Clear the screen and redraw the current line
  • Ctrl+G: Get a new line and abandon the current one
  • Ctrl+W: Delete part of the current command, from the beginning of the line to the cursor position.
  • Ctrl+K: Delete part of the current command, from the cursor position to the end of the line.

3. Go back to where you came from

Very simple, but oftentimes overlooked: You can quickly go back to the previous or your home directory with the following commands:

$ cd -      # return to previous directory
$ cd        # return to home directory

4. Type less, do more

The less you have to type, the more time you safe. Embrace aliases, default settings, and environment variables to make your life easier. Some useful aliases may include the following:

$ alias ls='ls --color=auto'             # colorize output of ls
$ alias ll='ls -la'                      # use long listing format
$ alias l.='ls -d .* --color=auto'       # show hidden files
$ alias ..='cd ..'                       # go up 2 dirs
$ alias ...='cd ../../../'               # go up 3 dirs
$ alias .4='cd ../../../../'             # go up 4 dirs
$ alias diff='colordiff'                 # colorize output of diff
$ alias ps='ps -eo pid,lstart,pcpu,cmd'  # more descriptive ps

Aliases can be removed via unalias.

Of course you can also define your own functions and enable certain options by default:

$ mkcd () { mkdir -p "$1"; cd "$1" }     # mkdir and cd into it
$ shopt -s cdspell                       # try to correct typos in path
$ shopt -s dotglob                       # include dotfiles in path expansion
$ shopt -s hostcomplete                  # try to autocomplete hostnames

You can type these commands in a specific terminal or put them in your .bashrc to make them apply to every terminal session going forward. Don't forget to $ source ~/.bashrc or open a new terminal before the changes stick.

5. Build a directory tree with a single command

Instead of repeatedly typing mkdir for every subdirectory you wish to create, you can create entire directory trees in a single line by passing the -p option to mkdir. Instead of typing:

$ mkdir test/dev
$ mkdir test/bin
$ mkdir test/sbin
$ mkdir test/etc
$ mkdir test/usr
$ mkdir test/lib
$ mkdir test/lib64

... you can simply type:

$ mkdir -p test/{dev,bin,sbin,etc,usr,lib,lib64}

6. Set up SSH keys for remote access

SSH keys provide a more secure way of logging into a remote machine with SSH than using a password alone. And: They save time.

The first step is to create an SSH key pair on your computer (the client machine):

$ ssh-keygen -t rsa

This will trigger a list of options to be displayed.

Press Enter on each of the options in order to use default settings. Entering a passphrase has the benefit of adding an additional security layer; however, the downside is that you will have to type it every time you use ssh. The complete output looks like this:

Enter file in which to save the key (/home/demo/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again: 
Your identification has been saved in /home/demo/.ssh/id_rsa.
Your public key has been saved in /home/demo/.ssh/id_rsa.pub.
The key fingerprint is:
4a:dd:0a:c6:d4:4e:43:ed:11:33:8c:74:44:4d:22:67 demo@somewhere
The key's randomart image is:
+--[ RSA 2048]----+
|     o + = +     |
|          .oo.   |
|    + .  o       |
|   = S = .o      |
|     .  o.E      |
|    . o +=o .    |
|      . = =o     |
|     . = = .     |
|                 |
+-----------------+

The public key is now located in /home/demo/.ssh/id_rsa.pub. The private key (identification) is now located in /home/demo/.ssh/id_rsa. All that is left to do is to copy the key pair to the remote machine:

$ ssh-copy-id user@123.45.67.89

Now you can log in to your remote machine without ever having to type your ssh password again.

7. Speed up extracting tar files

Fortunately, there are other people out there who always seem to forget the correct tar syntax and have come up with a handy solution. Include the following goody in your ~/.bashrc:

extract () {
    if [ -f $1 ] ; then
        case $1 in
            *.tar.bz2)  tar xjf $1      ;;
            *.tar.gz)   tar xzf $1      ;;
            *.bz2)      bunzip2 $1      ;;
            *.rar)      rar x $1        ;;
            *.gz)       gunzip $1       ;;
            *.tar)      tar xf $1       ;;
            *.tbz2)     tar xjf $1      ;;
            *.tgz)      tar xzf $1      ;;
            *.zip)      unzip $1        ;;
            *.Z)        uncompress $1   ;;
            *)          echo "'$1' cannot be extracted" ;;
        esac
    else
        echo "'$1' is not a valid file"
    fi
}

Use it on archive files that have one of the above file extensions with the following command:

$ source ~/.bashrc         # apply bashrc changes in current session
$ extract myFile.tar.gz

Beyond command-line tricks: Switch to a more powerful shell

Finally, a good way to boost your productivity is to simply move to a more powerful shell. There are a lot of good options out there, such as terminator which allows you to arrange terminals in a grid, and the immensely versatile ZSH as well as its plugin Oh My Zsh, which include features such as smart tab completion, shared command history, and globbing.