Linux is hard. Really hard. I didn’t start getting good at it until I started writing everything I learned down. Maybe this stuff will help someone else.


  • ctrl-u delete all left of the cursor
  • ctrl-k delete all right of the cursor
  • ctrl-w delete word left of the cursor
  • ctrl-y paste
  • ctrl-l clear
  • watch -n 2 date run the date command every 2 seconds and show the results as they happen fullscreen
  • tput colors display number of colors your terminal supports
  • echo $TERM shows what terminal you are using
  • watch -n 2 "dmesg | tail -30" continually watch the kernel messages for debugging

Recording sessions

  • script terminal_session.txt starts recording all the output from your terminal to a file
  • ctrl-d ends the recording session
  • less -R terminal_session.txt displays the session in its “raw” form for coloring, etc.

File system

  • mv {,new.}somefile.txt moves somefile.txt to new.somefile.txt using a bash feature called “brace expansion”
  • df -ah shows all your mounted disks and their free space
  • df -ih shows your inode information, can be useful when processes aren’t releasing files properly
  • du -sh * shows the file sizes for all files and folders in the current folder
  • tail -f shows the tail of a file and “follows” and outputs any changes made to that file
  • mv ~/Linux/Old/!(Tux.png|Tux2.png) ~/Linux/New/ move all files except one
  • tree shows current directory as tree (usually doesn’t come with stock OS)
  • tree -H outputs an HTML tree of a site with a base href
  • pushd . pushes your current directory into a temporary array
  • pushd switch between current director and the one on the top of your stack, like alt-tab on windows
  • popd recalls the last stored directory and sends you there
  • diff folder1 folder2 -q runs a diff on two folds and gives the brief differences
  • diff file1 file2 diff two files
  • chmod g+rw srv add read and write permissions for the group to the srv folder
  • chmod 600 file grant read and write privileges to the file owner
  • chmod 666 file grant read and write privileges to the owner, the group, and everyone
  • chmod 777 some_dir when chmodding a directory, make sure you use 7 instead of 6, execute on a directory doesn’t mean the same thing as a file

Archiving and compression

  • tar -zcvf test.tar.gz /home/jon/test create a compressed archive and store it to a new file called test.tar.gz
  • tar -xvf test.tar.gz uncompress and extract an existing archive
  • tar -zcvf test.tar.gz -C /home/jon/test . create a compress archive without an extra folder in it

Finding stuff

Search the root directory for anything with ‘something’ in it and pipe that to less:

  • find / -name 'something' | less
  • find / -iname '*something*' case insensitive with wildcard matching
  • find / | grep something 2>/dev/nul another way of doing the same thing, ignore errors
  • grep -rn 'something' recursively grep through files in the current dir, show the line numbers
  • grep -rn 'something' --exclude-dir=node_modules exclude a directory from your search
  • grep -rin contact_bg ./ | cut -f 1,2 -d: case insensitive search for “contact_bg” in current directory, split the results on colons and only show the first two columns from the result, basically hide the contents of the result
  • dpkg —get-selections lists packages that are installed
  • which man or which node find where your binary is located on the file system


  • /etc/hosts is a file that is like a personal DNS. You can map custom IPs to hostnames in it.
  • sudo netstat -tulpn display all the open ports on your machine

  • ssh -i ~/.ssh/id_rsa jon@ log into the machine with the user jon using the private key file ~/.ssh/id_rsa

  • curl perform a GET to
  • curl -I perform a HEAD against, shows status and other useful info without requesting the body

User management

  • usermod -a -G youre_mobile jon add existing user to existing group
  • Check the /etc/group file for group information
  • The /etc/sudoers file let’s you map groups or users to have sudo privileges

Release and renew IP

  1. sudo dhclient -r
  2. sudo dhclient
  3. sudo ifdown eth0
  4. sudo ifup eth0

Compiling programs

  1. ./configure
  2. make
  3. sudo make install install as root

Environment Variables

  • echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile adds a folder to your path for the bash shell
  • env list out all your environment variables
  • export SOMETHING="la la la la" set an environment variable
  • unset SOMETHING remove an env variable
  • echo $SOMETHING print out an env variable

Set time zone

  1. sudo rm /etc/localtime
  2. sudo ln -s /usr/share/zoneinfo/US/Pacific /etc/localtime
  • date —iso8601=seconds -u displays iso 8601 date time for UTC. Some version of linux don’t have this flag, see below
  • date +%FT%T%z displays iso 8601 local and works with all versions of date
  • date -d '4 days ago' relative dates


Generating a new ssh key

For the best security, you should be using one SSH key per device you use. An SSH key can optionally be password protected for extra security. When you generate a key, two files are created. One of the private key (don’t give it to anyone), the other is the public key, which is meant to be public.

  1. Make sure you don’t already have an ssh key you can use, check ~/.ssh
  2. ssh-keygen -t rsa -C ""
  3. ssh-add ~/.ssh/id_rsa

Using ssh-add puts your private key into ssh-agent that stores your password and private key while your machine is running

Make sure your ssh-agent is running with ssh-agent bash


  • cat /etc/*-release to figure out what distro you are running

Ubuntu unity

  • ctrl + alt + num5 hit any of the numpad numbers to align the windows
  • hold super key for keyboard shortcuts


  • make -j16 number of threads, 2x your number of cores makes sense”

I haven’t been able to write many blog posts lately. I’ve been very busy and have lots to share, but for the time being I am going to release a series of cheat sheets I’ve been compiling for my own reference. Theses posts will continually be updated as I find more useful commands. I’ll kick the series off with Git; the best source control on the planet.


  • git show HEAD~5:file.txt shows a file from 5 commits ago
  • git diff HEAD^ — file.txt diff file.txt to the last commit
  • git diff master..remotes/origin/master compares local master to remote origin master
  • git diff --stat summary of changes by file and line number changes
  • git rebase -i interactively rebase your commits, for example to squash commits into one before pushing
  • git reset --hard HEAD WARNING: reset your directory to the HEAD state
  • git init initalize a repo
  • git add --all stage all changes
  • git commit -m "the first commit" commit the changes
  • git checkout master -- file.html checkout a file from another branch
  • git checkout HEAD -- file.html checkout a file from HEAD

Merge conflicts

  • git checkout --ours something.txt
  • git checkout --theirs something.txt

There are plenty of fun and quirky features in Javascript. Beginners typically have trouble with the for in statement. In most other programming languages, a for in statement lets you loop through each of the items in an array or list. Javascript won’t yell at you if you try to use for in on an array, but the result will be really weird. In javascript, for in is meant to loop through each of the properties of an object. Let’s look at a bad example, followed by a good one.


var arr = [1,2,3,4,5];
var sum = 0;

for (item in arr) { sum += item; }

console.log(sum); // "001234" // WTF?!

I won’t go into the details of why this is bad, just don’t use for in with arrays. You should be using forEach or a simple for loop instead.


var jon = {
  name: 'Jon',
  age: 25

for (item in jon) {
  console.log(item + ' ' + jon[item]);
}   // name Jon
    // age 25

Prototype Pollution Problem

Even if you use for in correctly, you can still sometimes get unexpected results. It happens when you make changes to the prototype of an object. Let’s look at another example:

function Person(name) { = name;

Person.prototype.getName = function() {

var jon = new Person('Jon');

console.log(jon.getName()); // "Jon"

for (item in jon) {
  console.log(item + ' ' + jon[item]);
}   // name Jon
    // getName function .... // WTF?!

The latest version of javascript allows you to specify if you want a prototype method to be enumerable. I won’t go into the details of that. Rather, here is a good way to exclude prototype methods:

for (item in jon) {
  if (jon.hasOwnProperty(item))
    console.log(item + ' ' + jon[item]);
}   // name Jon

Recently I started learning Ruby on Rails. Mainly because it’s in high demand and ruby is supposed to be a clean, expressive language. Just being honest. It’s been pretty interesting so far. I started my professional programming journey in javascript and node, which has a very different philosophy than rails. In node land, the community respects small modules that have clearly defined responsibilities. It’s the developers job to string those small modules together to create something cohesive. Frameworks are generally looked down upon. Well, rails takes a very different approach. It happens to be a giant framework that bundles a ton of modules together for you.

The last website I built was on top of the express.js node framework. Express is a pretty minimal framework. It doesn’t give you all the bells and whistles that rails does. One of the big pain points I had was managing forms. Particularly with keeping the “create” page and the “update” pages in sync. Perhaps I was missing something in the express framework to help out. Early on with rails they showed the proper way to maintain a single view for both your “update” and “edit” forms. It was pretty thrilling to see they had already solved a problem I had and it came included with the package. On the other hand, I bet there’s a module out there that helps with just that issue.

I’m not sure I buy into either the “completely small modules” or “giant framework” philosophies. There are times when having features included in a framework can save a ton of time. There are other times when I want custom functionality that the framework author didn’t anticipate, it’s in those moments I wish I had small modules. Hopefully by learning rails I’ll be able to have a more informed opinion on the heated debate.

A few months ago a friend of mine got me setup with an account on his Linux box. This meant I had to relearn a ton of basic Linux commands I hadn’t used since high school. At first I was pretty frustrated. It was hard to get anything done. But I liked the idea of a slim development machine running in the cloud. One that I could leave on as long as I wanted. One that I could connect to from any machine (even and iPhone in a pinch). Since most of my development is just fancy text editing, I knew I had to step up me game.

Warning, generalization: a big epiphany for me as a programmer was understanding that all programs essentially start out as a bunch of text files sitting on a hard disk. There are a myriad of different file extensions, but most of them can still be opened with good old notepad++. Files that appear as a bunch of weird character typically mean that they have already been compiled and you need a special program to interpret them. Reason would follow that 20+ years of text based terminal systems would lead to pretty advanced tooling. Turns out that’s very true.

Anyway, let’s explore the things I needed to learn before I could be productive in a text only environment:


Step one was to learn Vim. Vim is a text editor that you can practically turn into an IDE. It’s modal, meaning that the same keyboard shortcuts do different things depending on what “mode” you are in. That is probably one of the biggest barriers to entry. What I didn’t realize was that Vim was the answer to all my problems with writing text, whether it be code or a blog post. In summary, if you want to be a text editing and code writing wizard, learn Vim. It’s worth every painful hour learning.

Learning Resources

Tmux and SSH

If you’re using a mac, you won’t need to use SSH because OSX is built on Unix. Meaning you can run Unix commands and programs from the Terminal app. For us folks still stuck on Windows, we need to be able to remote into another machine running Linux; that’s what SSH is for. Once you are connected to a Linux box, you need something the manage your sessions. Tmux is a well know application for Linux that stands for “terminal multiplexer”. This is a fancy way of saying, “it manages multiple windows and keeps your sessions running even when you disconnect from the machine”. It does other stuff too, but those are the highlights. It’s hard to understate how much more productive Tmux makes you when working in a text environment. I tried using both GNU Screen and Tmux, I like Tmux much better. Here’s me using Tmux to write this post:

using Tmux

Learning Resources

Look, I know this stuff is scary. I thought I’d never be able to learn it. But, with a bit of patience and perseverance, you’ll fall in love with the text way of life.