Ruby shell execution made easy and secure
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Shellex Build Status

Shellex allows you to run shell commands from your ruby scripts in a more robust and secure way than the built-in options. We're using this code in Beanstalk to keep the shell commands we execute secure against shell injection and keep every executed command under a tight timeout. This code also helps us construct complex shell commands easily thanks to the interpolation strategies listed below.


Add this line to your application's Gemfile:

gem 'shellex'

And then execute:

$ bundle

Or install it yourself as:

$ gem install shellex


Grabbing STDOUT output:

stdout, stderr = shellex("echo hello, world!")
# stdout => "hello, world!\n"
# stderr => ""

Grabbing STDERR output:

stdout, stderr = shellex("echo error here 1>&2")
# stdout => ""
# stderr => "error here\n"

Convenience methods:

shellex("echo hello, world").to_s # => "hello, world\n"
shellex("echo hello, world").stdout # => "hello, world\n"
shellex("echo error here 1>&2").stderr # => "error here\n"

Providing STDIN input:

shellex("cat -", :input => "hello").stdout # => "hello"

By default if you don't provide input we close the STDIN stream, but if you want you can leave it open:

shellex("cat /dev/stdin", :close_stdin => false)

Timeouts (default timeout is set to 5 minutes):

shellex("sleep 10", :timeout => 1) # raises ShellExecutionTimeout exception

Interpolation of arguments:

# to_s gets called on all arguments
shellex("echo ? ? ?", 1, "blah", :symbol)
# executes: echo '1' 'blah' 'symbol'

# ?& interpolates each array element separately
shellex("? ?& ?", "echo", [1,2,3,4], "abc")
# executes: 'echo' '1' '2' '3' '4' 'abc'

# ?& requires array to be present in the respective position
shellex("? ?& ?", "echo", 1) # raises ShellArgumentMissing

# ?~ escapes question mark
shellex("? ?~", "echo", "ello")
# executes: 'echo' ?

# ? by default will turn nil into empty string
shellex("echo ?", nil)
# executes: echo ''

# ?? will skip the argument if it's nil
shellex("echo ??", nil)
# executes: echo

# Shell injection protection
shellex("echo ?", "'; rm -Rf /; '")
# executes harmless: echo ''\''; rm -Rf /; '\'''


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request