Learn how to execute shell commands with the tty-command gem, a feature packed alternative to Ruby’s backticks or Open3 module.
Installing the tty-command gem
Make sure you have the tty-command gem installed:
gem install tty-command
Alternatively add the gem to your Gemfile and install it via bundler.
Executing a command
To execute a command and capture its output, create a TTY::Command
object and call its #run method with the command as an argument. For example:
require 'tty-command'
cmd = TTY::Command.new
result = cmd.run('git config --get remote.heroku.url')
url = result.out.chomp
Already this is more verbose than executing the command with backticks, but you’re also already getting more functionality in the form of colorized logging.
Handling exit errors
With backticks and Open3 you need to check the process status to make sure the command executed successfully. With tty-command you instead need to rescue from TTY::Command::ExitError
exceptions. For example:
require 'tty-command'
cmd = TTY::Command.new
begin
cmd.run('cal January')
rescue TTY::Command::ExitError
abort 'error: could not execute command'
end
Alternatively if you need more fine grained introspection into the error output you can call the #run! method which will return the result object instead of raising an exception.
Escaping arguments
One nice feature of tty-command is that it will escape arguments automatically:
require 'tty-command'
path = 'Ruby Mechanize Handbook.pdf'
cmd = TTY::Command.new
puts cmd.run('file --mime-type', path).out.chomp.split.last
This uses Shellwords module internally so it’s equivalent to the equivalent code using backticks, and much easier to read. One less detail to remember!
Comparison to alternatives
The tty-command gem has a number of features like colorized logging, automatic escaping, and dry_run mode, which you would have to implement yourself if you are executing shell commands with backticks or the Open3 module. This makes is good fit for projects where you need that extra functionality.
If you don’t need the extra features that tty-command provides, and/or avoiding gem dependencies is more important, backticks or Open3 might be a better choice.