FileUtils
The FileUtils module provides utilities for copying, moving, deleting, and creating files and directories in Ruby. It is part of the standard library, so you can use it without installing anything extra.
Overview
FileUtils is a good fit when your code needs to change the filesystem in a clear, repeatable way. It gives you named methods for common jobs, and those names are often easier to read than hand-written loops over paths. The module works especially well in scripts that set up projects, clean temporary files, or prepare deployment folders.
Loading FileUtils
require "fileutils"
If you prefer shorter method calls, you can include the module and call the methods directly. In many scripts, though, leaving the FileUtils. prefix in place makes the code easier to scan because it is obvious which operations touch the filesystem.
File operations
Copying and moving
require "fileutils"
FileUtils.cp("source.txt", "destination.txt")
FileUtils.mv("old.txt", "new.txt")
Copy and move are the two methods people reach for most often. cp keeps the original file in place, while mv changes its location or name. That split is useful because it makes the intent of the code easy to spot when reading a script quickly.
Deleting and creating
require "fileutils"
FileUtils.rm_f("temp.txt")
FileUtils.mkdir_p("path/to/folder")
Deletion and creation are usually the operations that deserve the most care. rm_f is helpful when you want cleanup to keep going even if a file is already gone, and mkdir_p is useful when nested folders need to exist before later steps run. Those methods keep setup code short without hiding what they do.
Directory operations
FileUtils can also work with whole directory trees. That includes creating folders, removing folders, and copying directory contents when a task needs to move a whole project or backup set at once. These methods are especially handy in build scripts where the same layout is prepared over and over again.
Permissions and links
require "fileutils"
FileUtils.chmod(0755, "script.sh")
FileUtils.ln_s("target", "link")
Permission changes and links are small operations, but they often matter in deployment and packaging code. A script that is meant to run must be executable, and a symlink can help point a tool at the current version of a file tree. Keeping those steps next to the filesystem action makes the setup easier to review.
Safety and logging
When you are testing a script, verbose and dryrun are valuable because they let you see what would happen before the code touches anything important. That is especially useful in cleanup code where a mistaken path could do real damage. A short preview run can save a lot of time when you are tuning a deployment or maintenance task.
require "fileutils"
# Preview what would happen without making changes
FileUtils.rm_rf("/tmp/build", verbose: true, noop: true)
# => rm -rf /tmp/build (printed but not executed)
# Actually perform the operation
FileUtils.rm_rf("/tmp/build", verbose: true)
# => rm -rf /tmp/build (printed and executed)
The noop option is particularly useful in scripts that run against production paths, where a dry run can catch mistakes before they do real harm. Combining it with verbose gives you a clear audit trail of what the script intends to touch, even when you are not ready to commit to the changes yet.
Practical example
require "fileutils"
def backup_directory(source, destination)
timestamp = Time.now.strftime("%Y%m%d_%H%M%S")
backup_name = File.basename(source) + "_" + timestamp
FileUtils.mkdir_p(destination)
FileUtils.cp_r(source, File.join(destination, backup_name))
end
This example shows a common pattern: create the destination first, then copy the source into a timestamped folder. The steps are simple, but the structure matters because backup code should be predictable and easy to audit. A short helper like this is often better than scattering filesystem calls through a larger script.
Common options
| Option | Description |
|---|---|
force | Do not raise an error if the destination exists |
verbose | Print operations to stdout |
preserve | Keep timestamps and permissions |
noop | Do not perform the operation |
dryrun | Preview the operation without running it |
These options are small, but they change how safe and chatty the operations feel in practice. force and noop are especially useful when a script needs to be forgiving or when you want to test the result before making real changes. Picking the right option makes the behavior much clearer to the person reading the code later.