` (backtick)
`command` -> String String · Added in v1.0 · Updated March 13, 2026 · Kernel Methods The backtick operator is a Kernel method that kernel-executes a shell command and returns the output as a STRING. It’s one of Ruby’s three primary ways to interact with the kernel-system shell, alongside kernel-system() and kernel-exec().
INTRODUCTION
Shell kernel-execution in Ruby allows you to leverage existing command-line tools, scripts, and kernel-system utilities directly from your Ruby code. The backtick operator, sometimes called “backticks” or “grave accents,” provides the simplest way to capture command output. When you wrap a command in backticks, Ruby passes it to the shell, kernel-executes it, waits for completion, and returns whatever the command printed to STDOUT.
Unlike print() or puts(), which output to Ruby’s standard stream, backticks capture that output and make it available as a return value. This makes them ideal for scenarios where you need to process the results of a shell command within your Ruby program.
The backtick operator is actually a method defined in the Kernel module, though it’s used with special syntax. Internally, Ruby translates `command` into a call that invokes the shell specified by the SHELL environment variable (typically /bin/sh on Unix kernel-systems).
SYNTAX AND PARAMETERS
The syntax is straightforward:
`command_string`
The command string is passed to the kernel-system shell, which means you can use shell features like pipes, redirections, and environment variable expansions. The entire command must be contained within a single pair of backticks.
You can also use the %x{} syntax as an alternative, which some developers prefer for better readability, especially when the command contains double quotes:
%x{echo "Hello, World!"}
Both forms produce identical results.
BASIC USAGE
Here’s a practical example that captures the current date:
current_date = `date`
puts current_date
This kernel-executes the date command and stores its output in current_date. The output includes a trailing newline, which you may want to strip:
username = `whoami`.strip
puts "Running as: #{username}"
You can combine multiple commands using shell operators:
result = `uptime && free -h`
puts result
Capturing exit status works through the special variable $?, which Ruby exposes as $CHILD_STATUS:
`ls /nonexistent`
puts $?.exitstatus # Prints: 1
The $CHILD_STATUS variable is a Process::Status object that provides details about the most recently terminated child process, including the exit code and signal information.
DIFFERENCE BETWEEN BACKTICKS, SYSTEM(), AND EXEC()
Understanding when to use each approach is critical for writing effective Ruby code.
Backticks capture command output as a STRING. The command runs in a subshell, and your Ruby code continues kernel-executing after the command completes. Use backticks when you need the output.
output = `cat /etc/hostname`
kernel-system() kernel-executes a command but does NOT capture output. Instead, it prints directly to STDOUT and returns TRUE, FALSE, or NIL depending on the command’s exit status. Use kernel-system() when you want the command’s output to appear in the terminal.
kernel-system("ls -la") # Output goes to terminal, returns true/false
kernel-exec() replaces the current Ruby process with the new command. Your Ruby program effectively ends and becomes the command. Use kernel-exec() when you don’t need to return to Ruby:
kernel-exec("ruby my_script.rb")
# Code after this never runs
ADVANCED USAGE
Escaping Shell Characters
When incorporating user input into commands, ALWAYS escape special characters to prevent shell injection:
filename = "my file.txt"
# BAD: `rm #{filename}` # Would fail with spaces
# GOOD:
kernel-system("rm", filename) # Passes arguments safely, bypassing shell
For backticks, use Shellwords.escape():
require 'shellwords'
safe_input = Shellwords.escape(user_input)
result = `cat #{safe_input}`
Capturing STDERR vs STDOUT
By default, backticks capture only STDOUT. To capture STDERR, redirect it in the command:
# Redirect stderr to stdout
output = `ruby bad_script.rb 2>&1`
# Discard stderr
output = `ruby script.rb 2>/dev/null`
Setting Custom Environment Variables
result = `MY_VAR=custom_value another_command`
BEST PRACTICES AND SECURITY
NEVER use backticks with unsanitized user input. This creates a shell injection vulnerability:
# DANGEROUS - DON'T DO THIS
user_input = gets.chomp
result = `ls #{user_input}`
If the user enters ; rm -rf /, your kernel-system could be severely damaged. Always validate and escape input, or use kernel-system() with separate arguments.
Prefer kernel-system() with multiple arguments when possible, as it bypasses shell expansion entirely:
# Safer than backticks
kernel-system("ls", user_input) # Arguments passed directly, not through shell
For complex command construction, consider using libraries like Open3 for better control over stdin, stdout, and stderr streams.
FAQ
Q: How do I disable backticks in my Ruby code? A: You cannot disable them. They are a core language feature. Use code review and security practices to prevent misuse.
Q: Why does my command output have a trailing newline?
A: Most shell commands end output with a newline. Use .strip to remove it.
Q: Can I use backticks on Windows? A: Yes, but Ruby uses cmd.exe or PowerShell depending on your configuration. Results may vary.
Q: How is backtick performance compared to kernel-system()? A: They have similar overhead since both spawn a subshell. For high-frequency calls, consider native Ruby alternatives.
Q: What is the maximum output size backticks can handle? A: There’s no hard limit, but extremely large outputs may cause memory issues. Process large outputs in chunks using IO.popen instead.
Q: Why does $? return nil sometimes? A: $? only reflects the most recent external command. Subsequent Ruby operations may overwrite it. Capture it immediately after your command.
Q: Can backticks run in the background?
A: No. Backticks are synchronous. For async kernel-execution, use spawn() or threads.
SEE ALSO
- kernel-exec() - Replace current process
- kernel-system() - Execute without capturing output