Oct 262007
 

I created a new rubygem called pulse. From the README:

Pulse adds an action to your rails project that can be used for external health checking. The most common use is by a http proxy such as haproxy. A proxy can be configured to hit your servers at a specified URL to see if the servers are healty. By default, they use the ”/” URL, but in many sites, this can have side effects like creating a session. Pulse adds a ”/pulse” URL which has no session and no logging.

The gem adds a route using the code described here: Add routes with a rails plugin or gem

Check out the gem and let me know what you think.

Oct 162007
 

On my current project, we release code often. As a result, we usually have at least one active branch along with the trunk. When bugs arise in production, we fix them in the branch and then merge them into the trunk. This constant merging was becoming a pain, so we automated it with a rake task that looks like:

desc 'merge changes from branch to trunk'
task :'svn:merge_to_trunk' do
  if %x[svn info].include? "branches"
    puts "Merging changes into trunk.  Don't forget to check these in."
    system "svn diff | patch -p0 -d /path/to/truck/checkout"
  end
end

This task first checks to see if we are on the branch. If our checkout is from the trunk, it does nothing. Then, it does a “svn diff” and pipes that into patch, which applies the diff to the local working copy for the trunk.

We added this task as a dependency on our commit task, which we run in order to check in (see Ruby: rake commit). Once we check into the branch, we switch over to the trunk working copy and run “rake commit” again to check in the changes.

Oct 102007
 

Notice this strange behavior with exit status and irb. The $? variable holds the exit status of the last command.

In plain ruby, everything works as expected:

% ruby -e "exit 4"
% echo $?
4

However, in irb, the exit status is 0:

% irb
irb(main):001:0> exit 4
% echo $?
0

It seems like irb ignores the exit status and always returns 0 (success). This introduces strange behavior around running tests. Test::Unit tests are run when the ruby process exits, and the exit status is non-zero if there were test failures. However, if the tests are run from irb, the exit status is 0 with failing tests.

In plain ruby:

% ruby failing_test.rb
Loaded suite failing_test
Started
E
Finished in 0.001127 seconds.
 
  1) Error:
test_fail(FailingTest):
RuntimeError:
    failing_test.rb:5:in `test_fail'
 
1 tests, 0 assertions, 0 failures, 1 errors
 
% echo $?
1

In irb:

% irb
>> require 'failing_test'
=> true
>> exit
Loaded suite irb
Started
E
Finished in 0.00077 seconds.
 
  1) Error:
test_fail(FailingTest):
RuntimeError:
    ./failing_test.rb:5:in `test_fail'
 
1 tests, 0 assertions, 0 failures, 1 errors
/usr/lib/ruby/1.8/irb.rb:76:in `throw': uncaught throw `IRB_EXIT' (NameError)
        from /usr/lib/ruby/1.8/irb.rb:76:in `irb_exit'
        from /usr/lib/ruby/1.8/irb/context.rb:226:in `exit'
        from /usr/lib/ruby/1.8/irb/extend-command.rb:24:in `exit'
        from /usr/lib/ruby/1.8/test/unit.rb:278
        from /usr/bin/irb:13
 
% echo $?
0
Oct 082007
 

Update (2/20/09): Check out Useful unix tricks – part 3 and Useful unix tricks – part 4

I covered a bunch of unix command line tricks in my previous blog post: Useful unix tricks. Here are some more.

Learn vi

Even if you prefer another text editor (such as emacs), it is worth your time to learn vi. vi is installed on every unix box, whereas emacs and others are not. Furthermore, many other unix tools use vi shortcuts (such as less), so learning the shortcuts will help out with other commands.

Use less instead of tail

I find that I often want to see the end of a file. The first command that jumps to mind is tail:

% tail /var/log/messages

Inevitably, I realize that I need more than the last 10 lines. So my next command prints more lines from the bottom:

% tail -n 100 /var/log/messages

However, an easier approach is to use less to display the whole file and then jump to the bottom (using Shift+g):

% less /var/log/messages
Shfit+g

Now, I can scroll up and down at will.

mkdir -p creates nested directories

By default, mkdir will only create a top level folder. So the following command will fail:

% mkdir some/nested/folder
mkdir: cannot create directory `some/nested/folder': No such file or directory

However, if you pass the -p parameter, mkdir will create all of the nested directories.

% mkdir -p some/nested/folder

ps will show process trees with the f flag

The ps command shows a list of running processes. The f flag will show the processes in a tree, so it is evident which processes started other processes. For example, a normal ps output looks like:

% ps
  PID TTY          TIME CMD
 6071 pts/2    00:00:00 zsh
 6287 pts/2    00:00:00 ps

The f flag output looks like:

% ps f
  PID TTY      STAT   TIME COMMAND
 6071 pts/2    Ss     0:00 /bin/zsh
 6288 pts/2    R+     0:00  \_ ps f
 5946 pts/1    Ss     0:00 /bin/zsh
 6126 pts/1    Sl+    0:18  \_ ruby ./script/server

Now, it is clear that I have two terminals (with zsh shell) running. One of them ran the ps command, and the other is running ruby script/server.

Normally, I use “ps afxww” which shows even more. The ax flags show all of the processes, not just the ones that I started. The ww flags tell ps to display long lines instead of truncating them.

Note: The mac version of ps does not support the f flag. In this case, use the program pstree instead. It can be installed via MacPorts.

lsof shows open files

lsof lists all open files on the system. This is useful for determining what is reading or writing to a certain file. For example, if you can’t unmount a drive because it is busy, run the following command to see what is still using the drive:

% lsof | grep /media/usbdisk

lsof can even be used to see what is listening on a given port. For example:

% lsof | grep 3000
ruby      6126       paul    5u     IPv4      25036              TCP *:3000 (LISTEN)

There is a ruby process (with process id 6126) listening on port 3000. Now, we can use ps to see the full process information:

% ps ax | grep 6126
 6126 pts/1    Sl+    0:26 ruby ./script/server