1. Skip to navigation
  2. Skip to content

The ELC Community Blog

A knowledge exchange on Ruby on Rails and Agile Development


Executing Shell Commands in Ruby

by josh on January 28, 2008

When in need of executing shell commands, it's easy enough in ruby to use exec(), system(), the ubiquitous backtick or %x{...}, but what's the difference between these?

irb(main):001:0> `ls`
=> "one\nthree\ntwo\n"
irb(main):001:0> %x{ls}
=> "one\nthree\ntwo\n"

Ok, so the backticks and %x{} are exactly the same. What about system()?

irb(main):003:0> system('ls')
one   three two
=> true

Nice, no '\n'. And now exec():

irb(main):004:0> exec('ls')
one   three two
bash$

Ah! it kicked me out of irb, meaning it kills the current Thread. Good to know!

Return Values

Process::Status Objects

irb(main):001:0> system('ls')
one   three two
=> true
irb(main):002:0> $?
=> #<Process::Status: pid=79599,exited(0)>
irb(main):004:0> 

$? accesses the status of the last system executed command, whether you use the backticks, system() or %{}.

Use '.exitstatus' to get the status:

irb(main):001:0>irb(main):001:0> system('ls')
one   three two
=> true
irb(main):002:0> $? # a magic ruby method
=> #<Process::Status: pid=79606,exited(0)>
irb(main):003:0> $?.exitstatus
=> 0
irb(main):004:0> 

Contrary to what you might think, 0 means success, 1 means failure. If you want to make the $? more readable, require English:

irb(main):001:0> system('ls')
one   three two
=> true
irb(main):002:0> $?
=> #<Process::Status: pid=79615,exited(0)>
irb(main):003:0> require 'English'
=> true
irb(main):004:0> $CHILD_STATUS
=> #<Process::Status: pid=79615,exited(0)>
irb(main):005:0> $CHILD_STATUS.exitstatus
=> 0
irb(main):006:0>

Parsing STDERR and STDOUT can only be done by logging and parsing logs. More to come...

Also posted to fr.ivolo.us

Comments

Tony Pitale at 4:41 AM on February 2 2008

Very nice. Looking forward to reading the follow-up on STDOUT and STDERR.

Add a comment


home | services | Ruby on Rails Development | code | blog | company