Cocaine
A small library for doing (command) lines.
Usage
The basic, normal stuff:
line = Cocaine::CommandLine.new("echo", "hello 'world'")
line.command # => "echo hello 'world'"
line.run # => "hello world\n"
Interpolated arguments:
line = Cocaine::CommandLine.new("convert", ":in -scale :resolution :out",
:in => "omg.jpg",
:resolution => "32x32",
:out => "omg_thumb.jpg")
line.command # => "convert 'omg.jpg' -scale '32x32' 'omg_thumb.jpg'"
It prevents attempts at being bad:
line = Cocaine::CommandLine.new("cat", ":file", :file => "haha`rm -rf /`.txt")
line.command # => "cat 'haha`rm -rf /`.txt'"
line = Cocaine::CommandLine.new("cat", ":file", :file => "ohyeah?'`rm -rf /`.ha!")
line.command # => "cat 'ohyeah?'\\''`rm -rf /`.ha!'"
You can ignore the result:
line = Cocaine::CommandLine.new("noisy", "--extra-verbose", :swallow_stderr => true)
line.command # => "noisy --extra-verbose 2>/dev/null"
# ... and on Windows...
line.command # => "noisy --extra-verbose 2>NUL"
If your command errors, you get an exception:
line = Cocaine::CommandLine.new("git", "commit")
begin
line.run
rescue Cocaine::ExitStatusError => e
e. # => "Command 'git commit' returned 1. Expected 0"
end
If your command might return something non-zero, and you expect that, it's cool:
line = Cocaine::CommandLine.new("/usr/bin/false", "", :expected_outcodes => [0, 1])
begin
line.run
rescue Cocaine::ExitStatusError => e
# => You never get here!
end
You don't have the command? You get an exception:
line = Cocaine::CommandLine.new("lolwut")
begin
line.run
rescue Cocaine::CommandNotFoundError => e
e # => the command isn't in the $PATH for this process.
end
But don't fear, you can specify where to look for the command:
Cocaine::CommandLine.path = "/opt/bin"
line = Cocaine::CommandLine.new("lolwut")
line.command # => "lolwut", but it looks in /opt/bin for it.
You can even give it a bunch of places to look:
FileUtils.rm("/opt/bin/lolwut")
File.open('/usr/local/bin/lolwut') {|f| f.write('echo Hello') }
Cocaine::CommandLine.path = ["/opt/bin", "/usr/local/bin"]
line = Cocaine::CommandLine.new("lolwut")
line.run # => prints 'Hello', because it searches the path
Or just put it in the command:
line = Cocaine::CommandLine.new("/opt/bin/lolwut")
line.command # => "/opt/bin/lolwut"
You can see what's getting run. The 'Command' part it logs is in green for visibility!
line = Cocaine::CommandLine.new("echo", ":var", :var => "LOL!", :logger => Logger.new(STDOUT))
line.run # => Logs this with #info -> Command :: echo 'LOL!'
Or log every command:
Cocaine::CommandLine.logger = Logger.new(STDOUT)
Cocaine::CommandLine.new("date").run # => Logs this -> Command :: date
POSIX Spawn
You can potentially increase performance by installing the posix-spawn
gem. This gem can keep your
application's heap from being copied when forking command line
processes. For applications with large heaps the gain can be
significant. To include posix-spawn
, simply add it to your Gemfile
or,
if you don't use bundler, install the gem.
Feedback
Security concerns must be privately emailed to [email protected].
Question? Idea? Problem? Bug? Comment? Concern? Like using question marks?
License
Copyright 2011 Jon Yurek and thoughtbot, inc. This is free software, and may be redistributed under the terms specified in the LICENSE file.