Page 5 of 28
Using The Shell Right
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
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.
Bruce Schneier plugin for Hudson
With the help of Mike Rooney, I created a plugin for Hudson that shows quotes from Bruce Schneier Facts: the BruceSchneier plugin.
Skittles Vodka
When walking through Ikea one day, I spotted the perfect bottles in which to make Skittles vodka. Starting with these, here is the process for making this infusion.
Materials
- 1300 grams of Skittles [$18 at Costco]
- 4 liters of vodka [$60 at Costco]
- Five 1 liter bottles [$25 at Ikea]
Tools
- Paper towels
- Colander
- Funnel
- 1 liter bowl
- 5 bowls
Sorting
The first tedious part of this process is sorting the Skittles into their various colors (ostensibly, flavors). I sat down in front of the Singapore Grand Prix with six plates: one for each of the five Skittles colors and an extra on which to dump packages for sorting. I bough a box of 36 normal-size (61 gram) packages of Skittles from Costco and ended up using 22 of the packs. To sort them, I poured a few packages onto one of the plates and separated the candies onto the five others.After consulting other who had made Skittles vodka, I settled on needing 240 Skittles per liter of vodka.
Assembly
Now comes the easy part. To get the Skittles into my narrow-mouthed bottles, I made a simple paper funnel and carefully poured the candies in. Easy. Then, I just used my liquid funnel to fill each bottle with vodka.Shake and Wait
After each of the containers was filled, I gave them a quick shake; within a few hours, much of the candies had dissolved. I left them overnight, and by the next day all that was left was a small bed of white pebbles in the bottom of each bottle.
Filter
Finally, the filtration. This step is the most difficult, because it requires a lot of patience even though you’re almost done!
A lot of the mass of Skittles is binder—corn starch and the like. It leaves a significant amount of scum onthe top of your Skittles vodka mix. To strain it off, I started by using standard office coffee filters, but those clogged very quickly. I switched to normal paper towels, which made filtering take about 5 minutes per bottle. After filtering, re-bottle and enjoy your super-sweet vodka rainbow!
Internet Birthday
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-decadeInternet 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.eBay Sucks at Domains
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.
Zombie Defense Station
I have finally completed my Zombie Defense Station. Inspired by this post that made it around the internet a few months ago, my kit contains a Sig P226 handgun, a Franchi SPAS-12 shotgun (as seen in Jurassic Park), and a Gerber Gator machete, which looks unnecessarily evil.
The construction was pretty easy and consists of the following parts
- ¼ inch beech plywood
- 1x4 pine plank
- ½ inch pine square
- ½ inch dowel
- 3/16 inch thick plexiglass
- Stencils from StencilEase
- Airsoft guns
- Gerber Gator machete
The first thing I did was get the airsoft guns and the machete, so that I could decide how big to make the enclosure. I bought the SPAS-12 online at the suggestion of my roommate when I said that I just wanted an awesome looking shotgun. We then trekked to various stores in the area in search of machetes. After turning up empty handed at OSH, Home Depot, and Target we hit the jackpot in Sports Authority’s camping section. For some reason, Gerber makes, and Sports Authority carries, this 15 inch, saw-back machete. While I think it is absolutely unnecessary for camping purposes, the Gerber Gator is a great zombie knife.
I settled on 34 inches long and 15 inches high, since that fit the SPAS-12 nicely with room for the machete underneath. I cut the box perimeter, screwed it square, and then screwed the back of the box to that. I affixed some 3.5 inch long pieces of ½ inch pine square to the corners, upon which the plexiglass would later rest. To mount the guns, I used some 2 and 3 inch long pieces of ½ in dowel that are screwed in place from the back of the box. The machete is held in place by some small metal hooks that I got in the Home Depot hardware aisle.
After the box was all assembled, I tossed a coat of gray paint on the inside, and bright red around the perimeter. I cut a piece of 3/16 plexiglass with a razor knife (doesn’t work very well - is there a better way?) and stenciled it using the stick-on stencils I orderd from StencilEase. To put the plexiglass into place, I used 3m Removable Mounting Squares.
My house is now safe from zombie attacks.
What is CrossFit?
Distilled down to the simplest terms, CrossFit workouts are about intensity, variability, and functionality.
The values of CrossFit’s World Class Fitness, are often summarized in 100 words:
Eat meat and vegetables, nuts and seeds, some fruit, little starch and no sugar. Keep intake to levels that will support exercise but not body fat. Practice and train major lifts: Deadlift, clean, squat, presses, C&J, and snatch. Similarly, master the basics of gymnastics: pull-ups, dips, rope climb, push-ups, sit-ups, presses to handstand, pirouettes, flips, splits, and holds. Bike, run, swim, row, etc. hard and fast. Five or six days per week mix these elements in as many combinations and patterns as creativity will allow. Routine is the enemy. Keep workouts short and intense. Regularly learn and play new sports.If all that is too simplified, let me elaborate. CrossFit is a workout regiment that embodies the above mentioned values. Unlike so many “gym rats” who think in disparate terms of cardiovascular and strength training, CrossFit does away with these distinctions for a methodology that is driven by results. Personal trainers at Globo Gym encourage long cardio stints of an hour or more “balanced” with similarly long sessions of strength training using Nautilus machines. In contrast, CrossFit workouts are mixed modal functional movements, performed at high intensity.
What is the difference and what make CrossFit better?
First, the focus on functional movements rather than isolated muscles. CrossFit not only trains your entire body to actually be used, but trains you in how to use your body to it’s fullest extent. Instead of a leg press machine, shoulder press machine, and lat pull-down, CrossFit workouts involve similar exercises, the squat, push press, and pull-up, either with bodyweight or barbells. Performing those latter exercises, which are done outside of the support of weight machines, means that technique, not just raw strength, is an important factor. Your body has to employ numerous minor muscles in concert to complete the moves safely and effectively. Ask yourself: do you have a machine guiding you to lift that dresser when helping a friend move?
Variety is a key part of CrossFit. The Workout Of the Day repeats on the scale of months and years - you can do CrossFit for quite some time before you repeat any single workout, and at the rate we’re going it’ll be a long time before any 3 days have the same prescription. This unique aspect of CrossFit is vitally important not only because keeps you from getting bored with exercise but it also keeps your body in limbo - there’s know way to prepare for the next move when it’s always different. This variety increases your ability to function optimally in the face of any task that is thrown at you, be it a new sport or a true emergency. Greg Glassman, the founder of CrossFit describes the importance of variability thusly:
We don’t have the agility of gymnasts, the power of a weightlifter, or the endurance of a marathoner but we have more agility, power, and endurance than any gymnast, weightlifter or marathoner. We do your stuff almost as good as you, you can’t do our stuff at all and we do stuff neither of us does way better than you can.What he’s saying that CrossFit athletes may not have the same ultimate performance in a single domain that specialists athletes have, we have a much broader portfolio of abilities. While the average marathon runner may be able to keep that sustained effort for hours, but they can’t jump more than 18 inches or lift their body weight off the ground. The weightlifter may be able to toss twice his weight overhead, but would suffer if asked to run a mile or do 20 pull-ups.
The intensity of CrossFit is, to me, the central factor that differentiates it from the way most people exercise. At the Globo Gym, you’ll see folks do their cardio workout, perhaps running on the treadmill, spinning on a stationary bike, or pedaling on a elliptical machine for 30 to 45 minutes. Then, they’ll amble around the weight machines for an hour or more, doing 3 sets of 10 with a minute of rest in between; guys who are trying to “get big” will split the weight session between “lats & back” on day, “chest & biceps” another, and “legs” the third. It all seems very organized, takes a lot of dedication and time.
In contrast, CrossFit workouts are usually 20-30 minutes and the longest ones take 45 to complete. That’s it. What do we do in that time? A whole lot more work than most people do in their entire 2-3 hour gym sessions, thanks to the ever present intensity. Even in CrossFit strength workouts like DT (3 rounds for time of 155lbs. deadlift x 12, clean x 12, jerk x 6), there’s a note that the workout is “for time” — no ambling around between sets in this workout. The reason this intensity is important is because is teaches you how to use the maximum extent of your body; to actually employ your muscles to their fullest. Intensity also plays into another big question that people have about CrossFit:
What about cardio?
Ahh, yes, what about cardio? Surely because we never do any long sessions of running, CrossFitters can’t have any endurance or stamina. Wrong. The widely touted measure of aerobic stamina and endurance is VO2 max, the amount of oxygen that your body can consume during sustained aerobic exercise — medium intensity stuff like distance running or biking. There’s a misconception that long bouts of aerobic exercise are what is required to build stamina and endurance, but this simply isn’t true. In the same way muscles must be taken beyond their limits and torn to stimulate growth, your ability to process oxygen must be pushed out of equilibrium in order to increase your capacity to process it (see CrossFit Journal issue 22; ask me if you’re really interested). Running at some level below your aerobic threshold (i.e. less than 100% VO2 max) will do little if anything to increase this ability. To push it out of equilibrium and induce growth you have to workout at 200% or more of your aerobic ability. In metabolic terms, you need to work the high-intensity phosphagenic and glycolytic pathways in order to improve the medium-low intensity aerobic pathway.
The Bottom Line
To really get CrossFi, you must understand what fitness really is (PDF) in the CrossFit view. First, CrossFit sees fitness as including ten metrics: cardiovascular endurance, stamina, strength, flexibility, power, coordination, agility, balance, and accuracy. Second is the ability to not just perform well at certain measures of fitness, but to perform admirably at any task that is thrown at you. The CrossFit games, which determines who is the fittest CrossFitter each year, embraces this — the competitors don’t know what the competition will entail until the day of the competition. Rounding out CrossFit’s standard for being “fit” is competency in each of the three metabolic pathways: phosphagenic, glycolytic, and oxidative. Fulfilling CrossFit’s standard means that one has total fitness, fitness across the broadest range of measures and challenges.
If you’re trying to “get big”, then by all means, stick to a rotating schedule of isolating muscles, hit the protein powder hard, skip the cardio, and enjoy the ditzy chicks you can pick up at the bar.
If you dig that ematiated Ethiopian look, like to run marathons, and want to pick up the vegan chick from Whole Foods to have some very boney sex, then keep at those super cardio sessions!
If you’re truly interested in challenging yourself, being in the best shape possible, and improving your abilities across numerous domains, then find a local CrossFit gym, and get in their boot camp. You’ll thank me later.
Edit 2008-04-24: CrossFit Radio talked about starting CrossFit last weekend. Also, CrossFit Brand X does scaled versions of the main site WODs on their forum.
I'm on the Genius Engineering blog
I was interviewed for the Genius.com Engineering Blog today.
Crontab Files
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.