Print color in shell terminal
Sometimes you might want to print something with color in a text terminal (by color I mean something other than the default text color). Put the following shell function to your ~/.bash_profile and you are go to good.
cecho() {
case $2 in
red) code=31;;
blue) code=34;;
green) code=32;;
cyan) code=36;;
purple) code=35;;
brown) code=33;;
white) code=37;;
*) code=30;;
esac
printf "\e[01;${code}m$1\e[0m\n"
}
Some examples:
cecho hello cyan cecho "something needs your attention" brown cecho "there's something terribly wrong, have to abort now" red cecho "this looks so pale" white cecho "will purple work too?" purple cecho goodbye blue
The above commands should output something like this ($TERM setting xterm-256color, tested on both OS X 10.7.2 and Ubuntu 11.10 64bit Server):

Open a new tab (or window) in Mac OSX Terminal and run command
[ UPDATE ]
After implementing the ruby code by user tig I was like, did I just make things more complicated than they should be? I was surprised that I didn’t first think about using the following applescript instead.
put the following codes in ~/.bash_profile
comm_tw() {
[ $# -lt 2 ] && return
osascript -e "
tell application \"System Events\" to tell process \"Terminal\" to keystroke \"$1\" using command down
tell application \"Terminal\" to do script \"$2\" in selected tab of the front window
" > /dev/null 2>&1
}
newt() {
comm_tw t "$1"
}
neww() {
comm_tw n "$1"
}
All I need to do then is to run either newt (to open a new tab or neww (to open a new window) and run command(s) in it. For example:
newt "ls -l ~; uptime" neww "date; who am i"
It’s worth noting that commands separated by semi-colon are allowed.
[ Initial Edit ]
I was looking for a solution to open a new tab (or window) and run a command (ssh for example) as sometimes I need to ssh to a number of hosts at once. I found the answer here. It’s almost what I needed for the tab part. I decided to change the ruby code (by sueruser.com user tig) a bit so I can use an option [ which is -w ] to run command in a new window. I am gonna post the code below. You can also fork me on github.
#!/usr/bin/env ruby
# A ruby script to open a new tab (or a new window) and run command in it on Mac OS X
# Modified based on the answer from tig regarding question posted at
# http://superuser.com/questions/174576/opening-a-new-terminal-from-the-command-line-and-running-a-command-on-mac-os-x
# Expands its feature a bit by allowing -w option top run command in a new window
# Usage Example:
# ./dt ls -l
# ./dt -w top
#
# Tested with Ruby 1.8.7
require 'rubygems'
require 'shellwords'
require 'appscript'
class Terminal
include Appscript
attr_reader :terminal, :current_window
def initialize
@terminal = app('Terminal')
@current_window = terminal.windows.first
yield self
end
def tab(dir, command = nil, mode = 't')
app('System Events').application_processes['Terminal.app'].keystroke(mode, :using => :command_down)
cd_and_run dir, command
end
def cd_and_run(dir, command = nil)
run "clear; cd #{dir.shellescape}"
run command
end
def run(command)
command = command.shelljoin if command.is_a?(Array)
if command && !command.empty?
terminal.do_script(command, :in => current_window.tabs.last)
end
end
end
Terminal.new do |t|
if ARGV.length>=1 && ARGV.first == '-w'
t.tab(Dir.pwd, ARGV[1, ARGV.length], 'n')
else
t.tab(Dir.pwd, ARGV)
end
end
As a side note, tmux can also be used for this kind of tasks with better scripting support. The only problem I might run into is hot key conflicts between local and remote hosts as most of the hosts I need to access are using tmux.
A real-time app made with node.js, socket.io, express …
This past weekend I decided to work on a pet project – build a real-time app using node.js.
Modules used: socket.io, express, jade, sqlite3.
Still screenshot:
Checkout the source codes at:
https://github.com/midnightcodr/news_board
Video demo is available here (audio-less).
Have fun.
[Fresh] Install node.js on Ubuntu server 11.10 (x64) via nvm step by step guide
sudo apt-get install build-essential sudo apt-get install libssl-dev sudo apt-get install curl git cd ~ git://github.com/creationix/nvm.git . ~/nvm/nvm.sh nvm install v0.6.7 # Current version as of this writing nvm use v0.6.7 curl http://npmjs.org/install.sh | sh # Optional to install npm but recommended
Note:
- It’s better to put the source command (. ~/nvm/nvm.sh) into your ~/.bashrc since the nvm command might get used quite often:
if [ -f ~/nvm/nvm.sh ]; then . ~/nvm/nvm.sh fi - If anything goes wrong during nvm install (for example, complaining certain library is not installed, I found the easiest way to re-start the install process is to install the missing library, followed by the removal of installation directory, ~/nvm/src/node-v0.6.7, for example
- On my ubuntu vm running off an i3 laptop, it took 7 minutes to install node.js v0.6.7, YMMV
- If you find yourself stuck inside node console, type command process.exit() to get out, solution found from here
Change git origin
Scenario:
you checkout a remote github repo as read-only:
git clone git://github.com/yourusername/oneofyourrepo
After you work on the local working directory for a while you decide that you would want to be able to push the changes back to github.
The easiest way is to either:
1) run the follow command on the root of the working directory:
git config remote.origin.url git@github.com:yourusername/oneofyourrepo
2) edit .git/config, look for section [remote "origin"] and change the url to
git@github.com:yourusername/oneofyourrepo
If you have already added the ssh public key of the host that you are working on to github.com, you should now be able to push the changes.
Credit goes to: http://stackoverflow.com/questions/3011402/leaving-github-how-to-change-the-origin-of-a-git-repo
Build a simple PHP template with str_replace()
You are given a task to notify a list of customers regarding their pin setting changes through their email address on file. There are many ways to accomplish this in PHP. One way I found quite interesting is through a simple php function str_replace. Let me demo through the following example (only showing how the message body is constructed, the email address part should be easy to take care of):
<?php
/* main.php */
function build_key($key) {
return '{{'.$key.'}}';
}
function gen_msg($format_str, $arr) {
$keys=array_map(build_key, array_keys($arr));
// $keys can also be generated by using the following code
// but I found using array_map is more elegant and fun
// $keys=array();
// foreach(array_keys($arr) as $k) {
// array_push($keys, '{{'.$k.'}}');
// }
return str_replace( $keys, array_values($arr), $format_str);
}
// here's the template
$template="Dear {{user}}, your pin number has been changed to {{pin}}.";
// here's the data, hard-coded in this example but it can be pulled from external sources as well
$data=array(
array( 'user'=>'John Smith', 'pin'=>'1234' ),
array( 'user'=>'Mr. S', 'pin'=>'9999' ),
array( 'user'=>'Customer', 'pin'=>'****' )
);
foreach($data as $d) {
printf("%s\n", gen_msg($template, $d));
}
Run the above code through php (cli) will output the following:
Dear John Smith, your pin number has been changed to 1234.
Dear Mr. S, your pin number has been changed to 9999.
Dear Customer, your pin number has been changed to ****.
[ Update ] I also added an OOP implementation of the above code, if you are interested you can checkout my code on github.
Combine regular expression and conditional statements in BASH
As we all know we can use conditional statements in BASH. For example, show usage if number of arguments is 0:
#!/usr/bin/env bash
if [ $# -eq 0 ]; then
echo "Usage: $0 start|stop|restart"
exit 0
fi
echo "going to run with \$1=$1"
We might also want to use regular expression to test if $1 is start, stop or restart if $# is no longer 0:
#!/usr/bin/env bash
function usage() {
echo "Usage: $0 start|stop|restart"
}
if [ $# -eq 0 ]; then
usage
exit 0
fi
if [[ ! $1 =~ ^(start|stop|restart)$ ]]; then
usage
exit 0
fi
echo "going to run with \$1=$1"
But wouldn’t it be nice if the tests can be combined together. With bash operator || the above code can be written as:
#!/usr/bin/env bash
function usage() {
echo "Usage: $0 start|stop|restart"
}
if [ $# -eq 0 ] || [[ ! $1 =~ ^(start|stop|restart)$ ]]; then
usage
exit 0
fi
echo "going to run with \$1=$1"
One more example using operator && instead:
#!/usr/bin/env bash
if [ -d ~/a_folder ] && [[ $1 =~ ^(install|remove)$ ]]; then
echo "going to $1 something"
else
echo "Folder ~/a_folder doesn't exist or you specified the wrong parameter:"
echo "Usage: $0 install|remove"
exit 0
fi
MySQL: select data whose certain column contains the specified values only
This problem could be best described by an example as below:
select * from mytbl; +------+------+ | k | v | +------+------+ | A | 1 | | A | 2 | | A | 3 | | B | 1 | | B | 3 | | C | 1 | | C | 3 | | C | 4 | | E | 2 | | E | 1 | | F | 5 | +------+------+
k, v are both char(10), not null.
I want to find out records whose v column is either 1 or 3 [and only 1 or 3, therefore in the above example the only qualified records are ('B', '1') and ('B', '3')]. This is just a simplified version of the problem I faced at work recently and I did find someone posting the similar question on Internet but I forgot to bookmark the url and I didn’t find its solutions interesting hence I pulled my hair a bit and came up with the following solution using group_concat and regexp:
select k, group_concat(distinct v order by v) as g from mytbl group by k having g regexp '^(1,?)?(3)?$'; +------+------+ | k | g | +------+------+ | B | 1,3 | +------+------+
If the requirement becomes v is either 1, 3 or 4 (again, 1, 3 or 4 only),
select k, group_concat(distinct v order by v) as g from mytbl group by k having g regexp '^(1,?)?(3,?)?(4)?$'; +------+-------+ | k | g | +------+-------+ | B | 1,3 | | C | 1,3,4 | +------+-------+
git branching by example
In this post I am going to demonstrate how to use git to apply a bug fix from the master branch to a feature branch that has already committed a new feature.
Example: fork a branch, add some new features to it. In the meanwhile add a bug fix to the master branch. We want to apply the bug fix to the feature branch while working on it but we decide it’s not time yet to add the new feature to the master branch. The simplest way I found (so far) is to create a temporary branch (and switch to it) on top of the master branch with the bug-fix commit, merge from feature branch, then switch to feature branch, merge changes from combined.
mkdir demo_proj cd demo_proj vi func.php
Put the following code into func.php and save.
<?php
function do_something() {
echo "hello\n";
return "wrong value";
}
git add . git commit -a -m "added function do_something in func.php" git checkout -b feature vi func.php
Add a new function new_feature() to func.php
<?php
function do_something() {
echo "hello\n";
return "wrong value";
}
function new_feature() {
return 999;
}
git checkout master vi func.php
Change word “wrong” to “right”:
<?php
function do_something() {
echo "hello\n";
return "right value";
}
git commit -a -m "fixed a bug in do_something()" git checkout -b combined git merge feature git checkout feature git merge combined git branch -d combined
After “git merge combined” the feature branch has the bug-fix from master branch while maintaining its own new_feature() function. Branch combined has accomplished its goal hence it’s OK to remove it.
Mac Lion 10.7.2 on HP 4530S
Followed instruction from http://www.tonymacx86.com/viewtopic.php?f=259&t=41546 to install Lion 10.7.2 on my newly bought HP 4530S (i3, 4GRAM, 320GB 7200RPM).
Notes:
- Got a kernel panic upon reboot after installing hp installer, reset BIOS to factory default fixed that.
- Alt key is the Command key.
- Had a hard time to exit from full screen mode, found solution from here.
- [01/07/2012] Installed VirtualBox 4.1.8 and tried to start Ubuntu 11.10 64bit server and it failed with the following error, downgraded to 4.1.6 solved the problem.
VT-x features locked or unavailable in MSR. (VERR_VMX_MSR_LOCKED_OR_DISABLED).
