July 30, 2007
Older: Last Modified File in Directory
Newer: Label Helper Makes It Into Edge Rails
I Can Has Command Line?
If you are a good developer, you are constantly trying to improve your efficiency. There are tons of little tips and tricks that you pick up over time that help with that. One of the things that has helped me a lot is the command line. Coming from php land, I seriously lacked bash skills. Hopefully the goods to follow will edumacate you on the ways of the bash and it’s friend the profile.
History
Everytime you run a command it gets stored in history. You can view your history at anytime by typing history.
$ history
2 mxmlc Main.as
3 mxmlc Main.as
4 mxmlc Main.as
# .... etc, etc, etc.
For a while, I would type history and then copy and paste the command in. Wrong. It’s much easier. You’ll notice the history prints each command with a number. You can run that command by number using !.
$ !4 # => runs mxmlc Main.as
That would run mxmlc Main.as (which was listed when I typed history). Nice eh? It’s the little things in life. That is nice and all but your history gets long over time (you can adjust the history size if you want). To deal with that use | (pipe) and grep in tandem like so:
$ history | grep svn
89 svn_up_and_log
198 svn st
199 svn add db/migrate/004_create_locations.rb
201 svn st
203 svn st
205 svn commit -c svn-commit.tmp
206 svn commit --help
207 svn commit -F svn-commit.tmp
208 svn st
209 rm -f svn-commit.tmp
210 svn st
213 svn st
216 svn export http://stikkitresource.rubyforge.org/svn/trunk/
Instantly, you are presented with every history item that matches ‘svn’. You can then use ! to call the item. Another handy history shortcut is !!. It re-runs the last command you used. This might not seem super helpful until you use it with sudo. How many times to you type ‘gem install some_gem_name’ and you get a permission denied error. Then you have to retype it with sudo in front (or press up to see the previous command and ctrl-shift-a to go to the beginning of the line). Next time try this:
$ sudo !!
Your previous command is ran with sudo in front. No more permissions issue. A big thank you to Mr. Newland for that one.
Aliases
These are quite possibly my favorite when it comes to bashing. My bash_profile is stuff full of various shortcuts. I’m of the belief that if you are typing the same thing over and over and it is more than 4 characters, you should have an alias for it. Below are some aliases that I use:
###########
# GENERAL #
###########
alias home='cd ~' # the tilda is too hard to reach
alias l='ls -lah' # l for list style, a for all including hidden, h for human readable file sizes
alias h='history' # shortcut for history
alias c='clear' # shortcut to clear your terminal
alias ..='cd ..' # move up 1 dir
alias ...='cd ../..' # move up 2 dirs
alias ebash='mate ~/.bash_profile &' # because i edit my bash_profile a lot with new things
alias rbash='source ~/.bash_profile' # same as previous, after editing you have to source it for the new stuff to work
###########
# TEXTMATE #
###########
alias e='mate . &' # open current dir
alias et='mate README app/ config/ db/ lib/ public/ test/ vendor/plugins &' # open current dir assuming rails
#######
# SVN #
#######
alias sup='svn up' # trust me 3 chars makes a different
alias sst='svn st' # local file changes
alias sstu='svn st -u' # remote repository changes
alias scom='svn commit' # commit
alias svnclear='find . -name .svn -print0 | xargs -0 rm -rf' # removes all .svn folders from directory recursively
alias svnaddall='svn status | grep "^\?" | awk "{print \$2}" | xargs svn add' # adds all unadded files
########
# RUBY #
########
alias irb='irb --readline -r irb/completion -rubygems' # use readline, completion and require rubygems by default for irb
# really awesome function, use: cdgem <gem name>, cd's into your gems directory and opens gem that best matches the gem name provided
function cdgem {
cd /opt/local/lib/ruby/gems/1.8/gems/; cd `ls|grep $1|sort|tail -1`
}
#########
# RAILS #
#########
alias ss='mongrel_rails start' # start up the beast
alias sc='script/console' # obvious
alias a='autotest -rails' # makes autotesting even quicker
# see http://railstips.org/2007/5/31/even-edgier-than-edge-rails
function edgie() {
ruby ~/rails/trunk/railties/bin/rails $1 && cd $1 && ln -s ~/rails/trunk vendor/rails && mate .
}
#########
# MYSQL #
#########
alias mysql=mysql5 # so i can use mysql command and don't have to type the 5 :) i'm lazy
So that was a lot to soak in but let me assure you it’s worth it. I’m sure others have even better aliases than me. You don’t have to put aliases in your .bash_profile. You can actually put them in .bash_aliases. If .bash_aliases doesn’t automatically get loaded, you can add this to your bash profile to force it to load:
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
SSH
Before rails and capistrano, I think I ssh’d maybe 20 times in my life. Since then, ssh is probably one of the things I use most from the command line. In fact, a little known secret is that ssh will get you the ladies (LLSSH for the Cool J fans). You probably know that you can ssh to a host like so:
ssh deploy@myfancydomain.com
You may not know that you can make shortcuts for you ssh accounts. Follow along:
$ mate ~/.ssh/config
# put the following in the file
Host nsync
HostName nsync.com
User jtimb
Now you can ‘ssh nsync
’ from the command line and it will behave equivalent to ‘ssh jtimb@nsync.com
’. You can put several of these shortcuts in the config file and there are other options but I’ll let you research those on your own.
Key pairs are also an ssh must but others have covered it far better than I could.
Dotfiles
You have sworn a solemn oath to never again type more than 4 chars from the command line. Cool. So where can you find more tricks from people far more bashish than I? A good place to start is a simple little camping app named dotfiles.org. Dotfiles has several different types of files that you can pour through to find even more functions, aliases and shortcuts.
Congratulations, you have been edumacated on the command line. Have a better one than me? Are any of mine wrong or could be improved? Let me know in the comments.
24 Comments
Jul 30, 2007
You can also use strings after ! and it will run the last matched command
eg.
!ssh (will run the most recent command starting with ssh)
!s (will run the most recent command starting with s)
etc.
Jul 30, 2007
I use “CTRL-R” for history. Once you’ve hit “CTRL-R”, you can start typing and it will do sub-string matching on your history file. Eg. “CTRL-R ssh”
You can keep hitting “CTRL-R” to cycle through other matches, so “CTRL-R ssh CTRL-R” will give you second-last “ssh” command you ran.
Jul 30, 2007
Thanks for the information on .ssh/config, I never even thought of that after so many years of using ssh. By the way, you might also find this useful
http://drawohara.tumblr.com/post/6584031
Jul 30, 2007
I always map my caps lock to ctrl because who uses caps lock anyway?
Then at the command line you can use emacs style shortcuts like ctrl+p and ctrl+n for arrow up and arrow down and ctrl+a, ctrl+e for beginning/end of line.
On a Mac, these work in almost all applications. I find using these shortcuts is more natural and faster than arrow keys.
Jul 30, 2007
Oooh, thanks for the reminder about edgie – that’s very cool.
Jul 30, 2007
alias home=‘cd ~’ # the tilda is too hard to reach
.. no need for that. `cd` on its own takes you home.
alias c=‘clear’ # shortcut to clear your terminal
.. try CTRL-l (that’s the letter ell), or CMD-K. SLightly different but both useful.
And another nice trick to add to the top of your .ssh/config. The following sets up ControlMaster multiplexing, so you can tunnel subsequent ssh connections over the first.
Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
Jul 30, 2007
One of my favourite things in bash is !$. This is the last parameter of the last command. Comes in handy much more often than you might think.
Jul 30, 2007
Minor things:
If you’ve mongrel installed,
script/server
will actually use that.mongrel_rails start
works as well, but you don’t get automagic log output to the console as withscript/server
.Using .irbrc is IMO tidier than aliasing the
irb
command.The
cdgem
function was very nice – thanks. I changed it to docd "$GEM_HOME/gems";
since I’ve set that environment variable to have gems installed somewhere else.Jul 30, 2007
Eep, rogue link tag. Sorry about that. Guess I found a bug ;)
Jul 30, 2007
Yay! Great shortcuts :D
My dumb mind didn’t think of aliasing all this stuff which for the most part I do all the time :/
I added
function hf() {
history | grep $1
}
which is a pattern I use constantly (together with ^R)
Jul 30, 2007
@Justin – Awesome.
@Nathan – Wow. Really cool.
@Seng – Yep, I saw that. It doesn’t complete with the user you are ssh’ing as. I was going to tinker with a script to do that from your history until Nathan posted his tip.
@noodl – Much slicker. Wondered how people did it in screencasts without spelling clear. :)
@Henrik N – yep, i know but I use topfunky’s hodel 3000 compliant logger which doesn’t like script/server and mongrel for some reason.
@Nicolas Sanguinetti – Cool. It’s funny how I type that all the time too but haven’t made a shortcut for it.
Jul 30, 2007
Could you share which terminal sotware are u using? It’s Coda from Panic? or something like that?
Jul 30, 2007
Could you share which terminal sotware are u using?
It’s iTerm, isn’t it?
Jul 30, 2007
Yes, it’s iterm. The latest release is quite snappy compared to some older versions. I love me some tabs.
Jul 31, 2007
Nice article – I’ve been looking for dotfiles.org for a few days now – I knew I’d seen it before, but couldn’t remember the name!
Incidentally, do you have any idea how to use the “synchronization features” that dotfiles.org claims to have? They talk about a command-line client, but it seems like it’s vapour at the moment…
Jul 31, 2007
@James – Hmm. No, I don’t know where the sync is. You could look at the forms that they have and probably pretty easily create something that would sync with www::mechanize or something.
Jul 31, 2007
I would add that the built-in bash command ‘hash’ is fun to see what you have been running in that window, and how often.
I’ve gotten into the habit of checking in all my dot-files and scripts into subversion, so it’s super-easy to get set up on a new box, and to keep all your accounts consistent.
Aug 19, 2007
Thanks for the dotfiles.org plug! And hey, I learned something (!!)… that’s why I love the command line, it’s as simple or as infinitely complex as you want to make it.
Aug 23, 2007
Thanks for the ssh tip.
I used it and needed to have add a port. So I did what I never do … the obvious. Thought I’d pass it along.
Host nsync
Hostname nsync.com
Port 3000
User jed
Aug 31, 2007
Quick, stoopid question time: what terminal app is that you’re using?
Sep 04, 2007
iTerm.
Sep 30, 2007
I use lots of aliases in my .bashrc as well.
I like to have 10,000 lines in my history file and the current history number in PS1 so I can bang ! a command from the history.
In .bashrc
Then I can find a command that I want to run again without typing it out:
So with !9669 I would have vimed camping-unabridged.rb again.
Here is my current .irbrc which brings in some Bash-like features:
http://pastie.caboo.se/pastes/102231
Oct 18, 2007
To speed things up a bit more try using the —wait or -w flag with TextMate. With this TextMate waits for file to be closed before running the next command. So to update my bash profile i use:
alias ebash='mate -w ~/.bash_profile; source ~/.bash_profile'
Nov 13, 2007
good stuff.
Sorry, comments are closed for this article to ease the burden of pruning spam.