Recently in Computers Category

I am about to give a talk at Super Happy Dev House 36 on Moose, the object system for Perl.

I've put the slides for my talk up on SlideShare.

Using The Shell Right

| 1 Comment | No TrackBacks

The most powerful part of Unix/Linux/BSD is the command line. In stock trim, the Unix shells are all very effective, but your time can be more effective by customizing the shell. I use bash, so I know that these things work in that shell, but they ought to be easily transferred to others as well.

Aliases

A good friend of mine, Jordan Sissel, once said that if you do something more than once, you're doing it wrong. His conjecture applies as much to your shell as it does to your browser—computers are great at repetitive tasks, so you shouldn't bore yourself with such things. Therein lies the most important thing you can do with your shell: make common tasks easier with aliases.

First things first, I use ls a whole lot, and, despite it's simple makeup, I often mistype the command. I don't care about being able to easily run Steam Locomotive, and there's no s or l command, so I replace those all with ls:

alias sl="ls"
alias l="ls"
alias s="ls"
alias ll="ls -l"
alias lh="ls -lh"
alias la="ls -la"
Another thing I do all the time is descend into directories, which means I need to get out of them, too:
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias .....="cd ../../../.."
alias ......="cd ../../../../.."
alias .......="cd ../../../../../.."

I always want extended regular expressions, and there are tons of things I don't want to search when I grep (though I use ack these days):

alias grep="egrep"
alias G="grep -n --color=always --binary-file=without-match --exclude=tags \
--exclude=*-min.js --exclude-dir='.[a-zA-Z]*' --exclude-dir='external' \
--exclude-dir='blib'"

Furthermore, I often want to do recursive greps of a entire codebase, sometimes case insensitive, and like everything else, I mistype it:

alias GR="G -r"
alias RG="GR"
alias GRI="G -r -i"
alias GIR="GRI"
alias IGR="GRI"
alias IRG="GRI"

If you do any sort of system administration, you need to grep the process list; make that easy:

alias paux="ps aux|grep -i"

Is someone shoulder surfing?

alias c="clear"
alias logout="clear; logout"

Matt Behrens tipped me off to this one—type -a tells you a lot more than the standard which:

alias which='type -a'

When I'm writing in a language that requires compilation, I use cowsay to break up the output of each run, so that errors are easy to distinguish between this run and the previous one:

alias gcc='cowsay "Hello"; gcc'
alias g++='cowsay "Hello"; g++'
alias make='cowsay "Hello"; nice -n 10 make'
alias javac='cowsay "Hello"; javac'

Machines that I SSH to often get their names as aliases; I've got a bunch more of these:

alias claudius="ssh -Y dinomite@dinomite.net"
alias caligula="ssh -Y dinomite@caligula.dinomite.net"

Prompt

There are numerous articles about pimping out your shell's prompt, many include previous command exit codes, the time, the current energy of the LHC, and the price of the S&P 500. I have a web browser, so I don't need all that information—I only put in my prompt things that are pertinent to the task at hand. The things that make up my prompt are a bit complicated, so I build it in stages. First, since I work on a lot of different machines, I always have the hostname in my prompt. To make it easy to tell which machine I'm on, I assign colors to the systems that I use most often:

HOSTNAME=`hostname|sed -e 's/\..*$//'`
if [ $HOSTNAME = 'Caligula' ] || [ $HOSTNAME = 'Caligula.local' ]; then
    export HOST_COLOR="\[\033[1;35m\]"
fi
if [ $HOSTNAME = 'claudius' ]; then
    export HOST_COLOR="\[\033[1;36m\]"
fi
if [ $HOSTNAME = 'dev1' ]; then
    export HOST_COLOR="\[\033[1;34m\]"
fi
if [ $HOSTNAME = 'svr-dev-rw1' ]; then
    export HOST_COLOR="\[\033[1;31m\]"
fi
if [ $HOSTNAME = 'drewfus' ]; then
    export HOST_COLOR="\[\033[1;30m\]"
fi

Next, I capitalize the hostname and make the colon separating it from the path red if I'm currently acting as root via sudo -s. This makes it very hard to forget that the consequences of actions are great at the current time:

COLON_COLOR='0m'
if [ ${UID} -eq 0 ]; then
    COLON_COLOR='1;31m'
fi
if [ ${UID} -eq 0 ]; then
    HOSTNAME="`echo $HOSTNAME|tr '[a-z]' '[A-Z]'`"
fi

Finally, build the actual prompt:

PS1=`echo -ne "$HOST_COLOR$HOSTNAME\[\033[00m\]\[\e[$COLON_COLOR\]:\[\033[33m\]\
w\[\033[00m\]\\[\033[01;33m\]\$\[\033[00m\] "`

What does this look like?
claudius:/usr/local$
And when root:
CLAUDIUS:/usr/local$

History

There are a lot of complicated commands that I only use occasionally; having a big history means if I've used it once, I can easily search and find the command later. The histappend options tells bash to append rather than overwrite the history file and cmdhist combines multi-line history commands into a single entry. It's often useful to run the same command repeatedly, and I find myself typing ls whenever I stop to think; setting HISTCONTROL and HISTIGNORE keeps those actions from filling up my history.

#"I know I've used that command before, but I can't remember the syntax"
export HISTSIZE=50000
shopt -s histappend
shopt -s cmdhist
HISTCONTROL=ignoredups
export HISTIGNORE="&:ls:ll:la:lh:sl"
export HISTTIMEFORMAT='%Y-%m-%d %H:%M:%S - '

Environment Variables

A lot of linuxes come with lackluster program defaults (emacs, more, etc.); you can get better ones by setting environment variables:

export PAGER=/usr/bin/less
export EDITOR='vim -X'
export BROWSER='firefox'
export CC=/usr/bin/gcc

Since we are in the 21st century, I use Unicode:

export LC_ALL="en_US.UTF-8"
export LANGUAGE="en_US.UTF-8"

Functions

I use Perl a lot, and have to deal with keeping modules the same across different systems; this function makes getting the installed version of a module easy:

function perlmodver {
    perl -M$1 -e 'print "Version " . $ARGV[0]->VERSION . " of " . $ARGV[0] . " is installed.\n"' $1
}

The thing I use awk for most often is '{print $n}', so I wrote fawk which you give a number and it des just that:

function fawk {
    first="awk '{print "
    last="}'"
    cmd="${first}\$${1}${last}"
    eval $cmd
}

awk also does math:

function calc {
    awk "BEGIN{ print $* }";
}

Tying It All Together

To keep things organized, I separate the above mentioned things into a few different files, so my .bashrc brings them all together. Additionally, I check for a .bash_local file, which isn't checked into subversion, so that I can have machine-specific alterations to my shell environment.

# .bashrc
source ~/.bash_global
source ~/.bash_aliases
source ~/.bash_functions
if [ -f ~/.bash_local ]
then
    source ~/.bash_local
fi

Screen Presets

| No Comments | No TrackBacks

Ubuntu's Screen Profiles package taught a lot of folks about how GNU Screen can be so much more than a fancy replacement for nohup(1). Since GNU Screen's name is difficult enough to search for, they have thankfully renamed the package to Byobu. Byobu provides users with a whole bunch of pre-defined aliases to make working within Screen easier, and make more sense by defining a useful status line. There's more that can be done with screen, the most notable in my view is creating predefined working environments that make getting yourself up and running when logging into a system easy.

I've got a number of different things that I commonly do where I want a number of different screen windows: running the deamons on our development server, connecting to the DB servers in each of the different environments, and developing an experimental project. For each of these applications, I have created a screenrc that I keep in my .screen/ directory; the basic format is this:

source $HOME/.screenrc

sessionname daemons
chdir /code/htdocs/dstephens/trunk/webroot/daemons

screen -t 'CONTROL' bash
screen -t 'aggregator' bash
screen -t 'autoEventWatcher' bash
screen -t 'emailReady' bash
screen -t 'sfUpload' bash
screen -t 'jmsCommandExecutor' bash
screen -t 'bouncedEmail' bash
select 0

First, I source my global .screenrc, which includes setting a statusline, larger scrollback buffer, multiuser and utf8. Next, giving the session a name makes it easier for me to figure out which one to reattach to later. Finally, I create and name all of the windows that I want to have in my session, in this case, one for each of the daemons that I want to be able to run.

To run a specific preset, just invoke screen with the -c option: screen -c ~/.screen/daemons. Easy.

With the help of Mike Rooney, I created a plugin for Hudson that shows quotes from Bruce Schneier Facts: the BruceSchneier plugin.

BruceSchneierPlugin

Internet Birthday

| No Comments | No TrackBacks

My Internet Birthday recently passed. What is an Internet Birthday, you ask? Why it's the arbitrary date that I've chosen to give when a website wants to know my birthday. You see, gentle reader, the vast majority of websites that ask for your birthday have no real reason to have it; most of the time it will simply be used for marketing. Whether or not you really care about that relatively innocuous usage, the real danger is that a lot of legitimate, organizations such as financial institutions, hospitals, and governments, use your birthday as an identifying piece of information—as though providing such a date is a verification of the person speaking or filling out a form.

Because of this abuse of a fairly public piece of information for the purpose of security, it is reasonable to want to keep your date of birth somewhat secret—or at least refrain from giving it to everyone who asks. Unfortunately, many services require you to provide a date of birth when signing up; some will give you a bonus if you give them your birthday. So as to not miss out on these services, I simply came up with a date that I use as my birthday when asked on the internet. I no longer hesitate to provide the information asked. Why not use a random date every time you sign up? Sometimes, particularly if you forget your password, a website will want you to enter your birthday at a later time to verify who you are. By choosing one date and sticking to it, you can always give the correct information.

Choosing an Internet Birthday

To come up with an internet birthday, simply choose a date!  Afraid you won't remember?  Understandable.  Choose something that makes sense to you: the first or last day of the month you were born, the day you were born modulo 12 to get a new month, or take Cheshire Catalyst's suggestion and use the start or end date for your astrological symbol.  As for the year, in most cases keeping the same year as your actual birth is the easiest and effective enough for our purpose.  If you're really paranoid, then just round to the nearest half-decade

Internet Family

Cheshire has updated his essay to suggest that an internet "Mother's Maiden Name" is also beneficial—and I agree.  I have an entire family based upon characters from a movie that I use for my financial accounts.  If you're serious about security, or you just can't remember the surnames names of your recent ancestors, then an Internet family based upon your favorite (or not so favorite) story is a great route to take.

If you go to http://ebay.com you will briefly see a naked text page with the following text, broken sentence structure and all:

The page you are looking for has been moved. If this page does not redirect you in 10 Secs,lease click here.

It will only be visible for a fleeting moment, because your browser will be redirected to www.ebay.com. The world's flea market fails the no-www test in the worst way - if you try to go to their website without a www subdomain, your are sent to said subdomain. eBay fails in a special way; rather than simply using an Apache RewriteRule:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

they send a web page containing an HTML meta refresh to send you to www.ebay.com. This is a clumsy and slow way to perform a redirect, particularly for the front-page of your website. If you are a website administrator or webmaster, please, don't be as hackish as eBay - embrace Class A no-www compliance or at least redirect using HTTP status codes rather than browser redirection.

Crontab Files

| 1 Comment | No TrackBacks

Crontabs are incredibly useful devices - the easiest way to regularly run a command at a specified time. The unfortunate part is that, as an operating system level function, their content is easily lost if you aren't careful about backups, or haphazardly reinstall your Unix system. A simple trick I learned is to keep your crontab entries in a file, say, .crontab in your home directory, rather than just editing your crontab directly (i.e. crontab -e). That way, you can be sure that all your important data, including your own user crontab, is in your home directory, and that's the one important thing to backup. To install a new crontab, simply run crontab ~/.crontab after having edited that file and your cron system will install your changes.

Caligula's Giant Ship

| No Comments | No TrackBacks

Like any good geek, I have a naming system for my computers and associated devices. Real systems — which I define as those that run SSH — are named after Roman Emperors; things that are computer-like but don't run SSH are named after Roman generals.

I have also taken to naming each of the disks attached to a machine after a land mass somehow connected to the Emperor it is named after. My main desktop is Caligula with the disks Capri, where Caligula lived under the care of Tiberius, Mauretania, which Tiberius annexed, and Germania, where Caligula accompanied his father on military campaigns as a young child. When I got a USB drive for keeping off-site backups, I needed to name it and though ships of the Roman Navy would be appropriate. What a pleasant surprise to find that Caligula had built a ship to transport the obelisk in St. Peter's Square which when it was found in the 1950's was named Caligula's "Giant Ship".

fawk

| No Comments | No TrackBacks

There are a lot of old-school Unix commands that can be strung together to form miniatures programs a solution where one doesn't already exist. Often times, they're great for nothing more than trimming the output from command line programs to make ocular searching easier. awk is one of these great little text processing utilities, though I usually find myself using it in only it's simplest fashion: to print a specific record from a line of input.

Caligula:~$ df -h|awk '{print $2}'
698Gi
298Gi
190Gi

That awk command, '{print $2}', is more than a bit cumbersome to type, so I keyed up a quick function in my .bashrc to make performing this quick operation easier:

Caligula:~$ df -h|fawk 2
698Gi
298Gi
190Gi

And the function:

function fawk {
    first="awk '{print "
    last="}'"
    cmd="${first}$${1}${last}"
    eval $cmd
}

Pages

About this Archive

This page is an archive of recent entries in the Computers category.

Cars is the previous category.

Cooking is the next category.

Find recent content on the main index or look in the archives to find all content.