less than 1 minute read

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

Updated: