HOWTO execute shell commands with Ruby TTY::Command

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.