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

PiriketSeverler at 7:11 PM on February 18 2008

Bir Pirikette Sen Koy! Web Site Down http://www.piriketseverler.tr.gg

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

You can use textile. For code, wrap in a <code lang="..."> tag.
home | services | Ruby on Rails Development | code | blog | company