Ruby for Scripting and Automation

· 5 min read · Updated March 7, 2026 · beginner
scripting automation devops beginner

Ruby is an excellent choice for scripting and automation. Its clean syntax, powerful standard library, and excellent OS integration make it perfect for automating repetitive tasks, processing files, and building command-line tools. This tutorial covers the fundamentals of using Ruby for automation scripts.

Why Use Ruby for Scripting?

Ruby was designed for programmer happiness, and that shows in scripting tasks. Here’s why Ruby works well for automation:

  • Readable syntax — Ruby reads almost like English, making scripts easy to understand and maintain
  • Rich standard library — Everything from file handling to HTTP requests is built-in
  • Cross-platform — Ruby runs on Linux, macOS, and Windows with the same code
  • Great ecosystem — Tools like Rake, Thor, and Bundler make complex scripts manageable

Running Your First Script

Create a file called hello.rb with this content:

#!/usr/bin/env ruby
# A simple Ruby script

puts "Hello, Automation World!"

Run it with:

ruby hello.rb

The #!/usr/bin/env ruby shebang line lets you run the script directly (./hello.rb) on Unix systems.

Working with Files

One of the most common automation tasks is processing files. Ruby makes this straightforward.

Reading Files

# Read entire file into memory
content = File.read('data.txt')
puts content

# Read file line by line (memory efficient for large files)
File.foreach('data.txt') do |line|
  puts line unless line.strip.empty?
end

Writing Files

# Write to a new file (overwrites existing content)
File.write('output.txt', 'Hello, World!')

# Append to existing file
File.open('log.txt', 'a') do |file|
  file.puts "#{Time.now} - Script completed"
end

Processing CSV Files

Ruby’s CSV library makes data processing simple:

require 'csv'

CSV.foreach('data.csv', headers: true) do |row|
  name = row['name']
  email = row['email']
  puts "#{name}: #{email}"
end

Running System Commands

Ruby can execute shell commands and capture their output.

Running Commands

# Run a command and get output
output = `ls -la`
puts output

# Or use the system method for more control
system('ls', '-la')

# Capture exit status
if $?.success?
  puts "Command succeeded"
else
  puts "Command failed with code: #{$?.exitcode}"
end

Using the open3 Library

For more control over command execution:

require 'open3'

stdout, stderr, status = Open3.capture3('ls', '-la')

if status.success?
  puts stdout
else
  puts "Error: #{stderr}"
end

Command-Line Arguments

Most automation scripts need to accept arguments:

# Access command-line arguments
filename = ARGV[0]
puts "Processing: #{filename}"

# Handle multiple arguments
ARGV.each_with_index do |arg, index|
  puts "Argument #{index + 1}: #{arg}"
end

# Use options with optparse for complex CLI tools
require 'optparse'

options = { verbose: false, count: 1 }

OptionParser.new do |parser|
  parser.on('-v', '--verbose', 'Increase verbosity') do
    options[:verbose] = true
  end
  parser.on('-c N', '--count=N', Integer, 'Repeat N times') do |n|
    options[:count] = n
  end
end.parse!

puts "Running #{options[:count]} times" if options[:verbose]

Automating Repetitive Tasks

Here’s a practical example: processing all files in a directory:

#!/usr/bin/env ruby
require 'fileutils'

# Process all .txt files in current directory
Dir.glob('*.txt').each do |filename|
  # Skip if file was modified today
  next if File.mtime(filename) > Time.now - 86400
  
  # Read and transform content
  content = File.read(filename)
  transformed = content.upcase
  
  # Write to new file
  new_filename = filename.sub('.txt', '_uppercase.txt')
  File.write(new_filename, transformed)
  
  puts "Processed: #{filename} -> #{new_filename}"
end

Working with JSON and YAML

Modern automation often involves configuration files:

require 'json'
require 'yaml'

# Read JSON
config = JSON.parse(File.read('config.json'))
puts config['database']['host']

# Read YAML
settings = YAML.load_file('settings.yaml')
puts settings['debug']

# Write JSON
File.write('output.json', JSON.pretty_generate(data))

Best Practices for Automation Scripts

  • Use require_relative for loading local libraries
  • Add error handling with begin/rescue blocks
  • Use Ruby’s logging library for script output
  • Make scripts idempotent — running twice should be safe
  • Add shebang lines for direct execution
  • Handle signals (SIGINT, SIGTERM) for graceful shutdown
# Graceful shutdown handling
trap('SIGINT') do
  puts "\nReceived interrupt. Finishing current task..."
  exit 0
end

When to Use Ruby for Automation

Ruby excels at:

  • File and directory processing
  • Text manipulation and parsing
  • Building CLI tools
  • Quick prototyping of automation ideas
  • System administration tasks

For heavy-duty data processing, consider combining Ruby with command-line tools like awk, sed, and sort via Ruby’s system integration.

Summary

Ruby provides a powerful yet readable way to automate tasks. Its file handling, system command integration, and rich standard library make it ideal for DevOps scripting. Start with simple scripts and gradually add complexity as needed. ENDADD

Environment Variables and Configuration

Automation scripts often need to read environment variables and handle configuration:

require 'json'

# Read environment variables
api_key = ENV['API_KEY']
database_url = ENV['DATABASE_URL'] || 'localhost:5432'

# Set default values
debug_mode = ENV.fetch('DEBUG', 'false') == 'true'

# Load configuration from JSON file
config = JSON.parse(File.read('config.json')) if File.exist?('config.json')

# Use environment variables in your script
puts "Running in #{ENV.fetch('RAILS_ENV', 'development')} mode" if debug_mode

Scheduling and Cron Integration

Ruby scripts work great with cron for scheduled automation:

#!/usr/bin/env ruby
# backup.rb - Example backup script for cron

require 'fileutils'
require 'time'

# Configuration
BACKUP_DIR = ENV['BACKUP_DIR'] || '/tmp/backups'
SOURCE_DIR = ARGV[0] || '/var/www'

timestamp = Time.now.strftime('%Y%m%d_%H%M%S')
backup_name = "backup_#{timestamp}.tar.gz"
backup_path = File.join(BACKUP_DIR, backup_name)

# Create backup directory if needed
FileUtils.mkdir_p(BACKUP_DIR)

# Create backup (using system tar command)
system('tar', '-czf', backup_path, '-C', SOURCE_DIR, '.')

if $?.success?
  puts "Backup created: #{backup_path}"
  # Clean old backups (keep last 7)
  Dir.glob(File.join(BACKUP_DIR, 'backup_*.tar.gz'))
     .sort[0...-7]
     .each { |f| File.delete(f) }
else
  puts "Backup failed!"
  exit 1
end

To run this daily at 2 AM, add to your crontab:

0 2 * * * /usr/bin/ruby /path/to/backup.rb /data/to/backup

Error Handling in Scripts

Robust scripts handle errors gracefully:

begin
  # Try to process the file
  content = File.read(input_file)
  processed = process_content(content)
  File.write(output_file, processed)
rescue Errno::ENOENT => e
  puts "Error: File not found - #{e.message}"
  exit 1
rescue Errno::EACCES => e
  puts "Error: Permission denied - #{e.message}"
  exit 2
rescue StandardError => e
  puts "Error: #{e.message}"
  puts e.backtrace if ENV['DEBUG']
  exit 3
ensure
  puts "Script finished at #{Time.now}"
end

This pattern ensures your script provides useful error messages and exits with appropriate codes.