Command Line Fu (Part 2)

This, part deux, continues part 1 of Command Line Fu.

Do This Over There

Spinning up and running a server somewhere on the internet is extremely easy these days. From Amazon EC2 to Slicehost having a remote machine running 24/7 is well within the reach of most devs. It also makes system administrators out of us. The powerful ssh command can help tame your network of servers so that you can spend a little extra time with friends and family. Most people think of ssh as a secure telnet (remember telnet?) but it’s oh so much more than that.

One of my favorite uses of ssh is in remotely executing commands. Here’s what one looks like:

$>ssh username@myserver.com 'apachectl -k restart'

That’s it. Simply put your command in quotes at the end of the ssh command line. The command is executed from your local machine but runs on the destination server. String 10 of those together in a script and you can restart your entire web server farm from your local machine by executing a single script. The ease and automatic nature of this hinges on setting up ssh for auto login.

You can take it to the next level by combining scp with ssh remote command execution. Consider having a stable of scripts that help you manage your servers all kept centrally on your local machine. When the need arises scp one of them over to the target machine and then use ssh to remotely execute it. Keeping all of those scripts locally reduces admin headaches by having copies distributed all over the place.

As an added bonus you can use ssh to securely tunnel out of wherever you happen to be. For example, you find yourself sitting in a strange coffee shop wanting to check your email without having to worry (note pop3 sends your email password in plaintext every single time it checks for new mail). You can easily divert your email over a secure connection so that anyone that happens to be monitoring network traffic doesn’t see your secrets.

$>ssh -f username@myserver.com -L 2000:mailhost.com:110 -N

The -f argument backgrounds ssh, username@myserver.com is your username at your servers hostname, -N tells ssh to not try executing this as a command on the remote machine. The -L argument is where the magic happens. In the args to -L 2000 is the port on your local machine, mailhost.com is your mail servers host name, and 110 is the port on the remote mail server machine. Now simply switch your email client to connect to localhost on port 2000 as your mail server. Now all of your email traffic for that account is secure from the point of your localhost to your server (your server forwards the request out to the real server from there). This technique works with just about any ports that you want to tunnel using your server as a middle man.

Interactive History

After working at the command line for any length of time you invariably need to re-execute some command again. You can either re-type it, often tedious, scroll through previous commands, takes forever, or you can search for it and just hit enter. Searching the command history is easy. Just hit CTRL-R at the prompt and start typing any part of the command. Search results will pop up:

(reverse-i-search)`sq': sqlite3 db/data.sqlite3

From this point you can hit Enter to execute the command or Right Arrow to put the command at the prompt so that you can edit it. If you have many similar results then you can continue hitting CTRL-R once you have a result to cycle through all matches.

Bashing History

Searching with interactive command history is handy. But, we can take it to a whole other level. Bash allows you to refer to previous commands and arguments withing those commands via a simple shorthand. Once you grok the shorthand you’ll be zipping through previous commands.

$>apt-get install git
Permission denied
$> sudo !!
sudo apt-get install git
Reading package lists... Done

The “!!” refers to the previous command in the history. So, executing “sudo !!” puts sudo in front that previous command. How many times have you executed a command only to re-execute it as sudo? Now it’s easy to do, eh? Here are some more variations to refer to previous commands:

!-2            # Refer to the command 2 back in the history (!-3, !-4, etc)
!find          # Previous command that starts with 'find'
!?find?       # Previous command that contains 'find'
!! -la         # Previous command adding -la as an argument
!!:1           # Refers to the first argument of the last command
!!:3-5        # Refers to arguments 3, 4, and 5 of the previous command
!!:0           # Refers to the command (no arguments)
!!:-2         # Refers to the command and the first two arguments

As you can see there is a lot of power there in referring to the previous command and arguments. Say, for example, you’re creating a tar file and realize that you have added an unwanted file (file2).

$> tar -xvf backup.tar file1 file2 file3 file4 file5
-- Ooops. Didn't want 'file2' in the list --
$>!!:-3 !!:5-7
tar -cvf backup.tar file1 file3 file4 file5
a file1
a file3
a file4
a file5

By using a simple shorthand the previous command was quickly executed sans the undesired argument. With a little practice this speedy but somewhat cryptic command structure becomes second nature.

So there you have it. My list of Master Command Line Fu tricks. Study them. Practice them. Before you know it you’ll pick that rabbit out of the hat while everybody sits out there wondering how the hell you did it.1


1. Gordon Gekko: “The richest one percent of this country owns half our country’s wealth, five trillion dollars. One third of that comes from hard work, two thirds comes from inheritance, interest on interest accumulating to widows and idiot sons and what I do, stock and real estate speculation. It’s bullshit. You got ninety percent of the American public out there with little or no net worth. I create nothing. I own. We make the rules, pal. The news, war, peace, famine, upheaval, the price per paper clip. We pick that rabbit out of the hat while everybody sits out there wondering how the hell we did it. Now you’re not naive enough to think we’re living in a democracy, are you buddy? It’s the free market. And you’re a part of it. You’ve got that killer instinct. Stick around pal, I’ve still got a lot to teach you. ”


This post is a part of the iDevBlogADay group of Indie development blogs. Thanks to @mysterycoconut for managing such a great site.