No commit activity in last 3 years
No release in over 3 years
Shell execution made easy and secure
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.3
>= 0

Runtime

>= 0
 Project Readme

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.

Installation

Add this line to your application's Gemfile:

gem 'shellex'

And then execute:

$ bundle

Or install it yourself as:

$ gem install shellex

Usage

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 /; '\'''

Contributing

  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