ZShell cannot invoke parameterized Rake Task

Just met a super wield question in zsh when I trying to invoke a parameterized rake task.
I have a rake task that helps me to create class and related test case for coffee script. It should be invoked in this way:

Invoke Rake Task
1
rake new:class[class_name]

I need to pass the parameter in a pair of square brackets, the syntax work pretty fine in bash shell. But when I do it in zsh, it yield error:
zsh: no matches found: new:class[BottleContainer]

So I have to create a new bash instance in zsh to invoke the shell. It is super wield and stupid.

Inject jQuery to current page

Now I’m hacking some web sites to try to grab the interesting informations from the page. But for some reason, all the sites I’m working on now, doesn’t included jQuery, they uses YUI or extJS, which makes me feel super inconvenient when trying hacking the page pattern.

Do I need to find a way to inject jQuery into the current page that I’m browsing.
Thanks to the browser address bar which allow us to execute javascript directly on current session. And also thanks to bookmark, which allow us to persists the script into bookmark, and invoke it with only one mouse click.

So I wrote this:

With this, we can quickly inject jQuery into current session in no time.

You can drag the following link to your browser favorites bar to:
Inject jQuery

Install specific version of tool with HomeBrew

HomeBrew is a convenient package manager for Mac user. For some reason I prefer Home Brew to Mac Ports.
Brew has a younger package repository since it has shorter history comparing to MacPorts. Younger repository means less options. And sometime it is hard for you to install the old-fashioned tool with brew.

Brew uses git to manage its formula repository, so you can list with git.
Typically, the repo is located at /usr/local. But since this path can be changed, so it is safer to reference this path via brew.
Brew call the repo path as prefix, so you can reference the path with brew --prefix
You can use the following shell command to enter the brew repo.

1
cd $(brew --prefix)

Since brew load formula from local, so before we install the app with brew, we need to ensure the repo is updated. We can use the following command to update the brew repo:

1
2
3
4
5
# Update brew
brew update
# update with git
cd $(brew --prefix) && git pull --rebase

To install specific version of the app, we need to checkout the specific version of the formula, we can get the versions and related git revision by brew versions command, and checkout specific version, then install the app:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
brew versions postgresql
# Output:
# 9.1.3 git checkout e088818 /usr/local/Library/Formula/postgresql.rb
# 9.1.2 git checkout dfcc838 /usr/local/Library/Formula/postgresql.rb
# 9.1.1 git checkout 4ef8fb0 /usr/local/Library/Formula/postgresql.rb
# 9.0.4 git checkout 2accac4 /usr/local/Library/Formula/postgresql.rb
# 9.0.3 git checkout b782d9d /usr/local/Library/Formula/postgresql.rb
# 9.0.2 git checkout 2c3b88a /usr/local/Library/Formula/postgresql.rb
# 9.0.1 git checkout b7fab6c /usr/local/Library/Formula/postgresql.rb
# 9.0.0 git checkout 1168d8f /usr/local/Library/Formula/postgresql.rb
# 8.4.4 git checkout c32bea0 /usr/local/Library/Formula/postgresql.rb
# 8.4.3 git checkout 9b2ef7c /usr/local/Library/Formula/postgresql.rb
# 8.4.1 git checkout 0495cf5 /usr/local/Library/Formula/postgresql.rb
# 8.4.0 git checkout a82e823 /usr/local/Library/Formula/postgresql.rb
git checkout a82e823 /usr/local/Library/Formula/postgresql.rb
brew install postgresql

If we cannot find the specific version that we want (Such as Postgres 8.3.11). don’t be disappointed, we can try to search the version repository.
Some of the old-fashioned tool which is not included in brew’s master repo might be provided in version repository.

Begin from Brew 0.9 provide the multiple repository support, user can use brew tap command to register alternative repositories besides the master repo. There are quite a some interesting alternative repos, such as versions and games.
These official alternative repos can be found on github

The formulas in alternative repositories cannot be used directly, but luckily the official ones are included in the search result.

1
2
3
4
5
brew search postgresql
# Output:
# postgresql
# homebrew/versions/postgresql8 homebrew/versions/postgresql9

In the search result, we can see there are 2 formulas are displayed with a path rather than just the formula name, which means these formulas are in a alternative repo.
The path to the formula follows the convention: <github username>/<repository name without "homebrew-">/<formula name>.
So homebrew/versions/postgresql8 means the file is located at https://raw.github.com/Homebrew/homebrew-versions/master/postgresql8.rb

To install it, we can install it directly or tap the repo first:

1
2
3
4
5
6
7
8
# Install directly
brew install homebrew/versions/postgresql8
# Tap
brew tap homebrew/versions
brew install postgres8

How to solve key_read failed error in git push

I assigned a dedicated ssh key pair for github repos.
And I have associated the key pair with github correctly in ~/.ssh/config.
But each time when I try to access github repos via ssh, both read(such pull or fetch) or write(such as push), I will get a strange error:

key_read: uudecode [some SSH key code]
ssh-rsa [SSH key code]
failed

I tried a lot to fix the problem, and finally I solved the problem by delete the file ~/.ssh/known_hosts
I assume the problem might be caused that there is some invalid association cached in the file. So maybe you can solve the problem by removing the related entries instead of delete the whole file.

How to launch Mac OS Terminal as Interactive Shell rather than Log-in Shell

As described in previous post, Mac OS launch its terminal as Log-In shell rather than Interactive Shell, which is different to default behavior of Unix and Linux. As a result, Terminal will load “bash_profile” as its profile rather than the normal “bashrc”.

This unique behavior might cause some problem when you try to port CLI tool from Unix or Linux.
Because basically, the ported app infers that the bash_profile should be loaded only once, and only when user just logged in. But in Mac OS, this inference is wrong, which can cause some weird problem.

This default behavior sometimes is annoying, and in fact, this Mac OS Terminal’s “unique” behavior can be configured. And even more, you can use other shell program, such as ksh, rather than the default bash.

Mac user can customize this behavior in Terminal’s Preferences dialog of Terminal app.
Terminal Preferences Dialog

If you choose the command to launch bash, the launched shell will become a interactive shell, which will load .bashrc file rather than .bash_profile file.

Bash Profile on Mac OS X

In Linux and Unix world, there are 2 common used shell profiles: ~/.bashrc and ~/.bash_profile. These two profiles are usually used to initialize user bash environment, but there still are some slightly differences between them two.
According to bash manual, .bashrc is “interactive-shell startup file”, and .bash_profile is “login-shell startup file”.

What’s the difference between interactive-shell and login-shell

Basically, the login-shell means the shell opened when user log in via console. It could be the shell opened on local computer after you entered correct user name and password, or the shell opened when you ssh to a remote host.
So according to the bash_profile will be loaded only once, that’s right after you logged into a computer, either locally or remotely.

And, on the other hand, the interactive-shell could be more widely used, be seen more often. It is the shell opened after you logged in, such as the shell opened from KDE or Gnome.

Mac Terminal’s Pitfall

According to the manual, the Terminal App on Mac is the typical “interactive-shell”, so theoretically Terminal should load “.bashrc” to initialize the shell environment. But the fact is Terminal doesn’t load the “.bashrc”, instead it load “.bash_profile” for initialization.
So in a word, Mac’s Terminal doesn’t follow the routine strictly. We need to be aware it.

And not all the shell are interactive! If the shell is not interactive, the Terminal App won’t load the profile file to initialize the environment.
A typical non-interactive shell in the shell that TextMate used to run command script, which means in TextMate’s shell, these environment variables, path and even alias you used in you daily life might not be available for TextMate’s command.
And also the most hurt one, the rvm function also won’t be available in TextMate’s command shell, which means if you call rake or rails in TextMate’s command script, you are very possibly got error because it cannot find proper gem or other resources.
So you should always remember to source and run the “.bash_profile” file or setup these values once again.

Powershell Script to rename computer without reboot

We found a computer name issue when building our private cloud environment on CloudStack over KVM. We found that KVM doesn’t support to rename new created instance automatically.
As a result, all the instance booted from the same disk image have the exactly same computer name, same administrator password.

So we need to do some manual provision work before user can use the new booted instances.
Administrator password can be changed in several ways, it is not a difficult job. But to rename the computer running Windows is not an easy work. The typical way is to call the WMI interface to rename the computer, which is taken as the most “formal” and “documented” way to rename the computer. But this approach require to reboot the instance, which is what we don’t like.

So we try some “hack” way to solve this problem, we use powershell scripts to hack the registry. By doing this, we can rename the computer without rebooting, and it works fine on our environment.
But since it is a hacking way, it only changed the most common values in registry, which means it won’t modify the rare ones and all kind of cached values. Such as the values cached in the SQL Server or MSMQ service, etc. So there might be some unknown potential issues. Take if on your own risk:

Here is the gist:

TextMate command to create new post for jekyll

Here is a bash script that acts as a TextMate command, which enables blogger to create new post without leaving TextMate.
It depends on “Post” task of the Rakefile in Jekyll Bootstrap.

New Post Command for Jekyll Bootstrap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cd $TM_PROJECT_DIRECTORY
title=$(CocoaDialog standard-inputbox \
--title "New Post" \
--informative-text "Title of the new post:")
[[$(head -n1 <<<"$title") == "2" ]] && exit_discard
title=$(tail -n1 <<<"$title")
output=$(rake post title="$title")
expr="^\(in (.*)\) Creating new post: (.*)$"
if [[$output =~ $expr ]]; then
project=${BASH_REMATCH[1]}
post=${BASH_REMATCH[2]}
echo "new post file created at $post"
exit_show_tool_tip
else
echo "Error"
exit_show_tool_tip
fi