Useful unix tricks - part 4

Here is part 4 of my useful unix tricks series:

Use mount -o bind to remount a filesystem

When you mount a filesystem in linux, anything that was in the existing directory is now hidden and out of reach. For example:

% touch /mnt/foo
% ls /mnt
./  ../  foo

% sudo mount /dev/sdb1 /mnt
% ls /mnt
./  ../

If you want access to those files again, you can remount / using mount -o bind:

% sudo mkdir /mnt2
% sudo mount -o bind / /mnt2
% ls /mnt2/mnt/foo
./  ../  foo

This command remounts / under /mnt2, so you can access any file through /mnt2.

less -R shows colors for control characters

Programs like Rails write log output with terminal coloring information. If you open these files in less, you’ll see something like:

% less development.log

ESC[4;36;1mSQL (0.2ms)ESC[0m   ESC[0;1mSET client_min_messages TO 'panic'ESC[0m
ESC[4;35;1mSQL (0.1ms)ESC[0m   ESC[0mSET client_min_messages TO 'notice'ESC[0m

If you add the -R flag to less, it tells less to output raw control characters, which will color your terminal:

% less -R development.log
SQL (0.2ms)   SET client_min_messages TO 'panic'
SQL (0.1ms)   SET client_min_messages TO 'notice'

Pressing alt+. will put in the previous command’s last argument

Pressing alt+. (the alt key and period) will drop the argument from the previous command into the terminal. For example:

% mv foo.txt bar.txt
% cat <press alt and .>

# this becomes
% cat bar.txt

This is especially useful for combo commands, such as unstaging and checking out a file in git:

% git st
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       modified:   foo
#

% git reset HEAD foo
Unstaged changes after reset:
M       foo

% git co <alt+.>

This is part of the emacs key bindings, and you can read more about them on stack overflow: bash – first argument of the previous command

Show git branch info in the prompt with coloring

I do a lot of development with git, and I have a lot of different git repositories. It’s handy to show git info in the prompt when I cd into a repo directory. At a minimum, I like seeing the current branch I have checked out.

For example, my prompt looks like:

host:~% cd repo
host:~/repo (master)%
host:~/repo (master)% git co -b some_branch
Switched to a new branch 'some_branch'
host:~/repo (some_branch)%

In zsh, getting a prompt like this is as simple as adding this to your .zshrc (or .zshenv) file:

git_prompt_info() {
  ref=$(/usr/local/bin/git symbolic-ref HEAD 2> /dev/null) || return
  echo " (${ref#refs/heads/})"
}

export PROMPT='%m:%~$(git_prompt_info)%# '

I like colors in my prompt as well, so my .zshenv looks like:

autoload -U colors
colors

git_prompt_info() {
  ref=$(/usr/local/bin/git symbolic-ref HEAD 2> /dev/null) || return
  echo " (${ref#refs/heads/})"
}

export PROMPT='%{$fg_bold[green]%}%m:%{$fg_bold[blue]%}%~%{$fg_bold[green]%}$(git_prompt_info)%{$reset_color%}%# '

After I load colors, I can use %{$fg_bold[color_name]} to change the following text to that color.

Use tmux instead of screen

For those that aren’t familiar with screen or tmux, here is the description from the tmux website:

tmux is a terminal multiplexer: it enables a number of terminals (or windows), each running a separate program, to be created, accessed, and controlled from a single screen. tmux may be detached from a screen and continue running in the background, then later reattached.

Being able to detach and reattach is really nice when working on remote servers. You can ssh to a server, start tmux, run a long running process and then detach. Hours later, you can ssh to the server again and reattach to the tmux window. The program continued running after you detached, and you can see the output as if you never left.

tmux is also great for working with others remotely. Everyone can ssh into one server and connect to the same tmux. Then, everyone can see the same file, commands, etc. This is often how we work together on deploys at Braintree Payments.

If you currently use screen, considering switching to tmux. They are very similar (both support everything I mentioned above), but tmux adds a few nice features:

  1. tmux allows you to split the screen vertically so you can have two windows side by side. This is great for working on servers. You can tail the log in one split, and work in the other so you can keep an eye on the logs. Screen lets you split horizontally, but I find vertical splits more useful on widescreen monitors since there is not as much vertical real estate.
  2. tmux adds a customizable status bar to the bottom of the terminal with information like which server you are on, the current time, tabs, etc.
  3. If different people all connect to the same tmux, it will adjust the viewable area to be the smallest window size. Larger monitors will see a grayed out background filling in the extra space. In contrast, screen might put output where the smaller windows cannot see it.

column -t will reformat input into columns

Use column -t when printing tabular output where the columns do not align. For example:

% print "one two\nthree four"
one two
three four

% print "one two\nthree four" | column -t
one    two
three  four

I use this all the time with the program pg_lsclusters, which prints out postgresql cluster information:

% pg_lsclusters
Version Cluster   Port Status Owner    Data directory                     Log file
8.4     backup_main 5433 down   postgres /var/lib/postgresql/8.4/backup_main /var/log/postgresql/postgresql-8.4-backup_main.log
8.4     main      5432 online postgres /var/lib/postgresql/8.4/main       /var/log/postgresql/postgresql-8.4-main.log

% pg_lsclusters | column -t
Version  Cluster      Port  Status  Owner     Data                                 directory                                           Log  file
8.4      backup_main  5433  down    postgres  /var/lib/postgresql/8.4/backup_main  /var/log/postgresql/postgresql-8.4-backup_main.log
8.4      main         5432  online  postgres  /var/lib/postgresql/8.4/main         /var/log/postgresql/postgresql-8.4-main.log

ctrl+p and ctrl+n cycle through terminal history

If you want to run a previous command in terminal, it’s common to press the up and down arrows to cycle through old commands. You can also use ctrl+p for previous and ctrl+n for next. I prefer these keys since it leaves my hands near the home row rather than having to reach for the arrow keys.