Question
How can I run shell commands from inside a Ruby program? Also, how can I capture the output of those commands and use it inside Ruby?
Short Answer
By the end of this page, you will understand the main ways Ruby can execute shell commands, how to capture standard output, how to detect success or failure, and when to use safer options such as system, backticks, %x, and Open3.
Concept
Ruby can launch external programs such as shell commands, scripts, and command-line tools. This is useful when your Ruby code needs to interact with the operating system or reuse existing tools.
Common examples include:
- listing files with
ls - running
gitcommands - calling image-processing tools
- executing deployment scripts
- reading output from utilities like
whoamiordate
The important idea is that Ruby and the shell are separate environments:
- Ruby runs your application logic
- The shell runs system commands
- Ruby can start a command, wait for it, and optionally capture its output
Ruby provides several ways to do this, and each one has a different purpose:
systemruns a command and returnstrueorfalsedepending on success- backticks
`command`run a command and return its standard output as a string %x(command)is another form of backticksOpen3gives more control and can capture standard output, standard error, and exit status separately
This matters in real programming because external commands often produce useful data, but they can also fail, hang, or behave differently across operating systems. Choosing the right Ruby method helps you write safer and clearer code.
Mental Model
Think of Ruby as a manager and shell commands as workers.
- If Ruby just wants a worker to do a task and report whether it succeeded, use
system. - If Ruby wants the worker to bring back a note with the result, use backticks or
%x. - If Ruby wants a full report with output, errors, and status, use
Open3.
Another way to picture it:
system= press a button and check whether the machine worked- backticks = press a button and collect the printed receipt
Open3= collect the receipt, the error log, and the final status code
Syntax and Examples
Basic ways to run shell commands in Ruby
1. system
Use system when you want to run a command and mainly care whether it succeeds.
success = system("ls")
puts success
- The command runs in the shell.
- Output is printed directly to the terminal.
- The return value is usually
truefor success andfalsefor failure.
2. Backticks
Use backticks when you want the command output as a Ruby string.
output = `whoami`
puts output
Example output:
alice
The value stored in output includes the command's standard output.
3. %x()
This is another syntax for backticks.
output = %x(date)
puts output
This is useful if backticks are harder to read in a longer string.
4.
Step by Step Execution
Example
output = `echo Hello`
message = output.strip
puts message
What happens step by step
1. Ruby sees the backticks
output = `echo Hello`
Ruby runs the shell command echo Hello.
2. The shell executes the command
The command prints this text to standard output:
Hello
Usually there is a newline at the end.
3. Ruby captures the output
The captured string becomes the value of output:
"Hello\n"
4. strip removes extra whitespace
message = output.strip
Now message is:
"Hello"
5. Ruby prints the cleaned result
Real World Use Cases
Practical uses
Running Git commands
A Ruby deployment script might check the current branch:
branch = `git branch --show-current`.strip
Calling system tools
A script may need the hostname of the machine:
hostname = `hostname`.strip
Processing files with external tools
Ruby might call tools like ffmpeg, convert, or tar.
system("tar", "-czf", "backup.tar.gz", "project_folder")
Automation scripts
A Ruby script can gather system information and generate a report.
disk_usage = `df -h`.strip
puts disk_usage
CI/CD and deployment
Build scripts often run commands such as:
bundle installgit pull
Real Codebase Usage
How developers use this in real projects
Guard clauses for failed commands
Developers often stop early if a required command fails.
unless system("git", "fetch")
abort("Failed to fetch latest changes")
end
This keeps scripts simple and clear.
Capturing output for validation
A program might check a command result before continuing.
ruby_version = `ruby -v`.strip
abort("Ruby is not installed") if ruby_version.empty?
Using Open3 for error handling
When stderr matters, Open3 is common.
require "open3"
stdout, stderr, status = Open3.capture3("git status --short")
abort(stderr) unless status.success?
puts stdout
Avoiding shell interpolation with user input
In production code, developers avoid unsafe string building.
filename =
system(, filename)
Common Mistakes
1. Expecting system to return command output
Broken example:
output = system("whoami")
puts output
Why this is wrong:
systemreturnstrueorfalse- it does not return the command output
Correct version:
output = `whoami`
puts output
2. Forgetting to remove the trailing newline
name = `whoami`
puts "User: #{name}!"
This may print awkward formatting because name often contains \n.
Better:
name = `whoami`.strip
puts "User: #{name}!"
3. Ignoring command failure
output =
puts output
Comparisons
Common Ruby options for running shell commands
| Method | Returns | Shows output in terminal | Captures stdout | Captures stderr separately | Best for |
|---|---|---|---|---|---|
system("cmd") | true/false | Yes | No | No | Run a command and check success |
`cmd` | String | No, captured instead | Yes | No | Get command output as a string |
%x(cmd) | String | No, captured instead | Yes |
Cheat Sheet
Quick reference
Run a command and check success
success = system("ls")
Run a command and capture output
output = `whoami`
output = output.strip
Alternative to backticks
output = %x(date)
Capture stdout, stderr, and status
require "open3"
stdout, stderr, status = Open3.capture3("ls missing_file")
Check the last exit status
output = `ls`
puts $?.success?
puts $?.exitstatus
Safer argument passing
system("ls", "-l", "/tmp")
Rules to remember
systemreturns success, not command output
FAQ
How do I capture shell command output in Ruby?
Use backticks or %x() if you want the command's standard output as a string.
What is the difference between system and backticks in Ruby?
system runs a command and returns whether it succeeded. Backticks run a command and return its output.
How do I get both stdout and stderr from a command in Ruby?
Use Open3.capture3 from Ruby's standard library.
How can I check if a shell command succeeded in Ruby?
With system, check the returned value. With backticks or Open3, inspect the exit status using $? or the returned status object.
Should I use shell commands or pure Ruby methods?
If Ruby's standard library can do the job, that is often more portable and easier to test. Use shell commands when you need existing system tools.
Is it safe to build commands with string interpolation?
Not always. If the values come from users or external input, prefer passing arguments separately to avoid shell injection issues.
Why does captured command output contain a newline?
Many shell commands print a trailing newline. Use .strip or .chomp to remove it.
Mini Project
Description
Build a small Ruby command runner that executes a system command, captures its output, and reports whether it succeeded. This demonstrates the difference between output, errors, and exit status in a practical script.
Goal
Create a Ruby script that runs a command entered in code, prints stdout and stderr separately, and shows the exit code.
Requirements
- Use Ruby and the
open3standard library. - Run at least one external command from the script.
- Capture standard output, standard error, and exit status.
- Print a clear success or failure message.
- Show the numeric exit code.
Keep learning
Related questions
How to Check Whether a String Contains a Substring in Ruby
Learn how to check if a string contains a substring in Ruby using include?, match, and multiline string examples.
How to Check if a Hash Key Exists in Ruby
Learn how to check whether a specific key exists in a Ruby hash using key?, has_key?, and include? with clear examples.
How to Check if a Value Exists in an Array in Ruby
Learn how to check whether a value exists in a Ruby array using include?, with examples, common mistakes, and practical use cases.