Question
How to Pass Command Line Arguments to a Rake Task in Ruby
Question
I have a Rake task that needs to insert a value into multiple databases.
I want to pass that value into the Rake task either from the command line or from another Rake task.
How can I do this in Ruby?
Example context:
# I want something conceptually like this:
rake my_task[some_value]
Or I may want one Rake task to call another and provide that value programmatically.
Short Answer
By the end of this page, you will understand how Rake task arguments work in Ruby, how to pass values from the command line, how to pass values from one task to another, and when to use task arguments versus environment variables.
Concept
Rake allows tasks to accept named arguments. This is useful when a task needs input at runtime, such as an ID, a filename, an environment name, or a value that should be inserted into one or more databases.
In Ruby, a Rake task can declare parameters like this:
task :import, [:value] do |t, args|
puts args[:value]
end
The key idea is:
:importis the task name[:value]declares the task argumentsargs[:value]reads the passed value inside the task
This matters because hardcoding values inside tasks makes automation brittle. Real projects often run tasks in different environments or with different inputs. Task arguments make the task reusable.
There are two common ways to pass data into a Rake task:
-
Task arguments
- Example:
rake import[123] - Best when the task has a small number of explicit inputs
- Example:
-
Environment variables
- Example:
VALUE=123 rake import - Best when shells, CI systems, or deployment scripts already use environment-based configuration
- Example:
When calling one Rake task from another, you can use invoke and pass arguments directly.
Mental Model
Think of a Rake task like a small command-line function.
- The task name is the function name
- The task arguments are the function parameters
- The code block is the function body
For example, this Ruby method:
def greet(name)
puts "Hello, #{name}"
end
is conceptually similar to this Rake task:
task :greet, [:name] do |t, args|
puts "Hello, #{args[:name]}"
end
If you imagine a Rake task as a function that can be run from the terminal, the argument syntax becomes much easier to understand.
Syntax and Examples
Basic syntax
A task with one argument:
task :insert_value, [:value] do |t, args|
puts "Value received: #{args[:value]}"
end
Run it from the command line:
rake insert_value[hello]
In some shells, especially zsh, you may need quotes:
rake 'insert_value[hello]'
Example with multiple arguments
task :copy_data, [:source_db, :target_db, :value] do |t, args|
puts "Copying #{args[:value]} from #{args[:source_db]} to #{args[:target_db]}"
end
Run it like this:
rake 'copy_data[main,archive,42]'
Step by Step Execution
Consider this task:
task :insert_value, [:value] do |t, args|
value = args[:value]
if value.nil? || value.empty?
puts "Missing value"
next
end
puts "Inserting #{value}"
end
Command:
rake 'insert_value[abc]'
Here is what happens step by step:
- Rake looks for a task named
insert_value. - It sees that the task expects one argument:
:value. - The string
abcis passed into that argument. - Inside the block,
args[:value]returns"abc". - The variable
valueis assigned"abc". - The
ifcondition checks whether the value is missing or empty.- It is not missing.
Real World Use Cases
Rake task arguments are useful in many practical Ruby projects.
Data maintenance
rake 'backfill_user_status[active]'
Use case:
- backfilling missing records
- updating old data after a schema change
- running one-off migration helpers
Multi-database operations
rake 'sync_value[promo_2025]'
Use case:
- insert a shared configuration value into several databases
- update tenant-specific records
- distribute seed data across environments
File processing
rake 'import_csv[customers.csv]'
Use case:
- importing reports
- parsing exports from another system
- running local admin scripts
Scheduled jobs and CI pipelines
VALUE=release_17 rake publish_config
Use case:
- passing deployment metadata
- running tasks in automated pipelines
- environment-based configuration in scripts
Admin and support tools
Real Codebase Usage
In real codebases, developers often wrap business logic in plain Ruby objects or service classes, and keep the Rake task thin.
Common pattern: thin task, real logic elsewhere
class MultiDbInserter
def self.call(value)
databases = ["users_db", "orders_db"]
databases.each do |db|
puts "Inserting #{value} into #{db}"
end
end
end
task :insert_value, [:value] do |t, args|
value = args[:value]
if value.nil? || value.strip.empty?
raise ArgumentError, "value is required"
end
MultiDbInserter.call(value)
end
Why this is common:
- the task stays easy to read
- the business logic can be tested separately
- the same logic can be reused from scripts, jobs, or controllers
Guard clauses
Developers often validate arguments early:
task , [] ||
, args[]
puts
Common Mistakes
1. Forgetting to declare task arguments
Broken code:
task :insert_value do |t, args|
puts args[:value]
end
Why it fails:
- The task does not declare
[:value], so the argument is not defined as expected.
Correct version:
task :insert_value, [:value] do |t, args|
puts args[:value]
end
2. Not quoting the command in shells that expand brackets
Problematic command:
rake insert_value[hello]
In some shells, this may be interpreted by the shell instead of being passed to Rake.
Safer version:
rake 'insert_value[hello]'
3. Assuming a task can be invoked repeatedly without re-enabling
Broken expectation:
Rake:[].invoke()
[].invoke()
Comparisons
| Approach | Example | Best for | Notes |
|---|---|---|---|
| Rake task arguments | rake 'import[123]' | Small explicit inputs | Clean and readable for direct task usage |
| Environment variables | VALUE=123 rake import | CI, scripts, deployment | Good when tools already provide env vars |
| Hardcoded values | value written inside task | Quick experiments only | Not flexible and not reusable |
Task arguments vs environment variables
Task arguments
- good for required positional inputs
- easy to see from the command itself
- useful when manually running tasks
Environment variables
- good for external configuration
- useful in CI/CD pipelines
- better when passing many settings or secrets
Calling a task directly vs extracting logic to a class
Cheat Sheet
Declare a task with arguments
task :name, [:arg1, :arg2] do |t, args|
puts args[:arg1]
end
Run from the command line
rake 'name[value1,value2]'
Access arguments
args[:arg1]
args[:arg2]
Validate required input
raise ArgumentError, "arg1 is required" unless args[:arg1]
Call one task from another
Rake::Task[:name].invoke("value1", "value2")
Run a task again in the same process
Rake:[].reenable
[].invoke()
FAQ
How do I pass an argument to a Rake task from the command line?
Declare the task with arguments and run it like this:
task :example, [:value] do |t, args|
puts args[:value]
end
rake 'example[hello]'
Why do I need quotes around task[arg]?
Some shells interpret square brackets before passing the command to Rake. Quotes ensure the full string reaches Rake unchanged.
How do I pass arguments from one Rake task to another?
Use invoke:
Rake::Task[:example].invoke("hello")
Why does my task only run once when I call it multiple times?
Rake tasks are executed once per process by default. Use reenable before invoking again.
Should I use task arguments or environment variables?
Use task arguments for small explicit inputs. Use environment variables when values come from CI, deployment scripts, or external shell environments.
Can a Rake task have multiple arguments?
Mini Project
Description
Build a small Rake task that accepts a value and inserts it into a list of simulated databases. This project demonstrates how to define task arguments, validate input, loop through targets, and reuse the task from another task.
Goal
Create a Rake task that accepts a value from the command line and applies it to multiple database targets, with a second task that calls it programmatically.
Requirements
- Create a Rake task named
insert_into_allthat accepts one argument calledvalue - Validate that
valueis present before continuing - Simulate inserting the value into at least three databases by printing messages
- Create another task named
demo_insertthat callsinsert_into_allwith a sample value - Make sure the first task can be called again from the same process if needed
Keep learning
Related questions
How to Call Shell Commands from Ruby and Capture Output
Learn how to run shell commands in Ruby, capture output, check exit status, and choose the right method for scripts and apps.
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.