HOWTO execute shell commands with Ruby Backticks

How do you execute shell commands in Ruby? One of the easiest approaches is to use Ruby’s built-in backticks (aka backquotes).

Executing a command

If you need to execute a command and capture its output, simply enclose the command string in backtick characters instead of double or single quote characters. For example:

url = `git config --get remote.heroku.url`.chomp

Ruby translates the backtick syntax into a Kernel method call, executes the command for you, returns its output, and stores the process status in a global variable.

Why the call to chomp? Many commands will terminate their output with a newline character, which you often don’t want to include in the string you get back in Ruby. Alternatively you might want to split the output into lines or perform a regexp scan, depending on how the command formats its output and what you want to extract.

Checking the process status

Even if you are only interested in the output of a command, you usually still want to check the process status to make sure the command executed correctly and exited without any errors. Otherwise your script might continue to run with incorrect input.

Ruby sets the $? global variable to a Process::Status object which you can use to check if the command executed successfully, like this:

output = `cal January`

if $?.success?
  puts output
  abort 'error: could not execute command'

Process::Status objects also have an #exitstatus method for checking the exit code.

Escaping arguments

Interpolation is supported in backticks as with strings, which is useful when you want to pass options or arguments to the command that you construct in Ruby. For example:

require 'shellwords'

path = 'Ruby Mechanize Handbook.pdf'

puts `file --mime-type #{Shellwords.escape(path)}`.chomp.split.last

Escaping isn’t handled for you automatically, so if you have any arguments which need to be escaped you’ll need to escape them yourself with the Shellwords module.

Comparison to alternatives

The biggest benefit of executing commands with backticks is the simplicity: no gem dependencies to install, and nothing to require or configure, just a little syntax. So it’s a good fit for “quick and dirty” scripting where you only need to run a simple command.

Consider the Open3 module if you need to do more, like writing input to the command or capturing error output. The tty-command gem might be a better fit if you’re working on a bigger project that would benefit from more abstraction and added functionality.