Monday, 14 April 2008

bash fun

Quote by Terrence Parr:
My Motto: "Why program by hand in five days what you can spend five years of your life automating?"


We do a lot of actions that make a directory interesting for us and then we want to cd intro that directory. Consider:

hg init my_repo; cd my_repo
mkdir -p a/b/c/d; cd a/b/c/d
mv my_file /tmp; cd /tmp


Boring, repetitive and not DRY.

Lesson 1: You can do something like this:
mkdir -p a/b/c/d; cd !$

Better, but not good enough for me. I'd like to type
go hg init my_repo
go mkdir -p a/b/c/d
go mv my_file /tmp


So we need to create a short bash script, don't we?

How do we get last argument of the script (we'll need that). Provided that $1 is the first argument, $2 - second and $# - argument count and $@ all arguments as an array... yes, you guessed it. It's ${!#}

How nice and intuitive. Try those: $$# ${$#} ${${#}} $@[$#].

So do we have all that we need?
goj@abulafia tmp $ cat go
#!/bin/bash
$@
cd ${!#}


goj@abulafia tmp $ ./go echo ~
/home/goj
goj@abulafia tmp $


Epic FAIL. ./go script is executed in child shell. When it terminates it's parent's CWD is unaffected. We have to source it:

goj@abulafia tmp $ . ./go echo ~
/home/goj
goj@abulafia ~ $


But this syntax sucks. Luckily, alias is our friend:

goj@abulafia tmp $ echo 'alias go=". go-source-me"' >> ~/.bashrc
goj@abulafia tmp $ mv go ~/bin/go-source-me


You have to have ~/bin in your PATH.

goj@abulafia tmp $ go echo ~
/home/goj
goj@abulafia ~ $


Ta-dam!

No comments: