Module: Cheetah
- Defined in:
- lib/cheetah.rb,
lib/cheetah/version.rb
Overview
Your swiss army knife for executing external commands in Ruby safely and conveniently.
## Features
* Easy passing of command input
* Easy capturing of command output (standard, error, or both)
* Piping commands together
* 100% secure (shell expansion is impossible by design)
* Raises exceptions on errors (no more manual status code checks)
* Optional logging for easy debugging
## Non-features
* Handling of interactive commands
Defined Under Namespace
Classes: DefaultRecorder, ExecutionFailed, NullRecorder, Recorder
Constant Summary collapse
- BUILTIN_DEFAULT_OPTIONS =
{ :stdin => "", :stdout => nil, :stderr => nil, :logger => nil }
- READ =
0
- WRITE =
1
- VERSION =
Cheetah version (uses [semantic versioning](semver.org/)).
File.read(File.dirname(__FILE__) + "/../../VERSION").strip
Class Attribute Summary collapse
-
.default_options ⇒ Hash
The default options of the Cheetah.run method.
Class Method Summary collapse
-
.run(*args) ⇒ Object
Runs external command(s) with specified arguments.
Class Attribute Details
.default_options ⇒ Hash
235 236 237 |
# File 'lib/cheetah.rb', line 235 def @default_options end |
Class Method Details
.run(command, *args, options = {}) ⇒ Object .run(command_and_args, options = {}) ⇒ Object .run(*commands_and_args, options = {}) ⇒ Object
Runs external command(s) with specified arguments.
If the execution succeeds, the returned value depends on the value of the ‘:stdout` and `:stderr` options (see below). If the execution fails, the method raises an ExecutionFailed exception with detailed information about the failure. (In the single command case, the execution succeeds if the command can be executed and returns a zero exit status. In the multiple command case, the execution succeeds if the last command can be executed and returns a zero exit status.)
Commands and their arguments never undergo shell expansion — they are passed directly to the operating system. While this may create some inconvenience in certain cases, it eliminates a whole class of security bugs.
The execution can be logged using a logger passed in the ‘:logger` option. If a logger is set, the method will log the executed command(s), final exit status, passed input and both captured outputs (unless the `:stdin`, `:stdout` or `:stderr` option is set to an `IO`, which prevents logging the corresponding input or output).
The actual logging is handled by a separate object called recorder. By default, DefaultRecorder instance is used. It uses the ‘Logger::INFO` level for normal messages and the `Logger::ERROR` level for messages about errors (non-zero exit status or non-empty error output). If you need to customize the recording, you can create your own recorder (implementing the Recorder interface) and pass it in the `:recorder` option.
Values of options not set using the ‘options` parameter are taken from default_options. If a value is not specified there too, the default value described in the `options` parameter documentation is used.
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/cheetah.rb', line 348 def run(*args) = args.last.is_a?(Hash) ? args.pop : {} = BUILTIN_DEFAULT_OPTIONS.merge(@default_options).merge() streamed = compute_streamed() streams = build_streams(, streamed) commands = build_commands(args) recorder = build_recorder() recorder.record_commands(commands) pid, pipes = fork_commands(commands) select_loop(streams, pipes, recorder) pid, status = Process.wait2(pid) begin check_errors(commands, status, streams, streamed) ensure recorder.record_status(status) end build_result(streams, ) end |