rubyguides

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.

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

OptionDescription
forceDo not raise an error if the destination exists
verbosePrint operations to stdout
preserveKeep timestamps and permissions
noopDo not perform the operation
dryrunPreview 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.

See Also

  • File — for low-level file operations
  • Dir — for directory traversal and listing
  • ERB — for generating file content programmatically