Module: FileUtils
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Classes:
| |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
StreamUtils_
|
|
Instance Chain:
self,
StreamUtils_
|
|
Defined in: | lib/fileutils.rb |
Overview
Namespace for file utility methods for copying, moving, removing, etc.
What’s Here
First, what’s elsewhere. Module FileUtils:
-
Inherits from
class Object
. -
Supplements
class File
(but is not included or extended there).
Here, module FileUtils provides methods that are useful for:
-
Creating
. -
Deleting
. -
Querying
. -
Setting
. -
Comparing
. -
Copying
. -
Moving
. -
Options
.
Creating
-
.mkdir: Creates directories.
-
.mkdir_p, .makedirs, .mkpath: Creates directories, also creating ancestor directories as needed.
-
.link_entry: Creates a hard link.
-
.ln_sf: Creates symbolic links, overwriting if necessary.
-
.ln_sr: Creates symbolic links relative to targets
Deleting
-
.remove_dir: Removes a directory and its descendants.
-
.remove_entry: Removes an entry, including its descendants if it is a directory.
-
.remove_entry_secure: Like .remove_entry, but removes securely.
-
.remove_file: Removes a file entry.
-
.rm_f, .safe_unlink: Like .rm, but removes forcibly.
-
.rm_r: Removes entries and their descendants.
-
.rmdir: Removes directories.
Querying
-
.uptodate?: Returns whether a given entry is newer than given other entries.
Setting
-
.chmod: Sets permissions for an entry.
-
.chmod_R: Sets permissions for an entry and its descendants.
-
.chown: Sets the owner and group for entries.
-
.chown_R: Sets the owner and group for entries and their descendants.
-
.touch: Sets modification and access times for entries, creating if necessary.
Comparing
-
.compare_file, .cmp, .identical?: Returns whether two entries are identical.
-
.compare_stream: Returns whether two streams are identical.
Copying
-
.copy_entry: Recursively copies an entry.
-
.copy_file: Copies an entry.
-
.copy_stream: Copies a stream.
-
.cp_lr: Recursively creates hard links.
-
.cp_r: Recursively copies files, retaining mode, owner, and group.
-
.install: Recursively copies files, optionally setting mode, owner, and group.
Moving
Options
-
.collect_method: Returns the names of methods that accept a given option.
-
.commands: Returns the names of methods that accept options.
-
.have_option?: Returns whether a given method accepts a given option.
-
.options: Returns all option names.
-
.options_of: Returns the names of the options for a given method.
Path Arguments
Some methods in FileUtils accept path arguments, which are interpreted as paths to filesystem entries:
-
If the argument is a string, that value is the path.
-
If the argument has method
:to_path
, it is converted via that method. -
If the argument has method
:to_str
, it is converted via that method.
About the Examples
Some examples here involve trees of file entries. For these, we sometimes display trees using the ) tree command-line utility, which is a recursive directory-listing utility that produces a depth-indented listing of files and directories.
We use a helper method to launch the command and control the format:
def tree(dirpath = '.')
command = "tree --noreport --charset=ascii #{dirpath}"
system(command)
end
To illustrate:
tree('src0')
# => src0
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
Avoiding the TOCTTOU Vulnerability
For certain methods that recursively remove entries, there is a potential vulnerability called the Time-of-check to time-of-use, or TOCTTOU, vulnerability that can exist when:
-
An ancestor directory of the entry at the target path is world writable; such directories include
/tmp
. -
The directory tree at the target path includes:
-
A world-writable descendant directory.
-
A symbolic link.
-
To avoid that vulnerability, you can use this method to remove entries:
-
.remove_entry_secure: removes recursively if the target path points to a directory.
Also available are these methods, each of which calls FileUtils.remove_entry_secure:
Finally, this method for moving entries calls FileUtils.remove_entry_secure if the source and destination are on different file systems (which means that the “move” is really a copy and remove):
-
.mv with keyword argument
secure: true
.
Method FileUtils.remove_entry_secure removes securely by applying a special pre-process:
-
If the target path points to a directory, this method uses methods
File#chown
andFile#chmod
in removing directories. -
The owner of the target directory should be either the current process or the super user (root).
WARNING: You must ensure that ALL parent directories cannot be moved by other untrusted users. For example, parent directories should not be owned by untrusted users, and should not be world writable except when the sticky bit is set.
For details of this security vulnerability, see Perl cases:
Constant Summary
-
LOW_METHODS =
Internal use only
# File 'lib/fileutils.rb', line 2615singleton_methods(false) - collect_method(:noop).map(&:intern)
-
METHODS =
Internal use only
# File 'lib/fileutils.rb', line 2622singleton_methods() - [:private_module_function, # :nodoc: :commands, :, :have_option?, :, :collect_method]
-
OPT_TABLE =
Internal use only
This hash table holds command options.
{}
-
VERSION =
# File 'lib/fileutils.rb', line 183"1.7.2"
Class Method Summary
-
.collect_method(opt)
Returns an array of the string method names of the methods that accept the given keyword option
opt
; the argument must be a symbol: -
.commands
Returns an array of the string names of FileUtils methods that accept one or more keyword arguments:
-
.have_option?(mid, opt) ⇒ Boolean
Returns
true
if methodmid
accepts the given optionopt
,false
otherwise; the arguments may be strings or symbols: -
.options
Returns an array of the string keyword names:
-
.options_of(mid)
Returns an array of the string keyword name for method
mid
; the argument may be a string or a symbol: -
.cd(dir, verbose: nil, &block)
(also: #chdir)
mod_func
Changes the working directory to the given
dir
, which should beinterpretable as a path
: -
.chdir(dir, verbose: nil, &block)
mod_func
Alias for #cd.
-
.chmod(mode, list, noop: nil, verbose: nil)
mod_func
Changes permissions on the entries at the paths given in
list
(a single path or an array of paths) to the permissions given bymode
; returnslist
if it is an array,[list]
otherwise: -
.chmod_R(mode, list, noop: nil, verbose: nil, force: nil)
mod_func
Like .chmod, but changes permissions recursively.
-
.chown(user, group, list, noop: nil, verbose: nil)
mod_func
Changes the owner and group on the entries at the paths given in
list
(a single path or an array of paths) to the givenuser
andgroup
; returnslist
if it is an array,[list]
otherwise: -
.chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
mod_func
Like .chown, but changes owner and group recursively.
-
.cmp(a, b)
mod_func
Alias for #compare_file.
-
.compare_file(a, b)
(also: #identical?, #cmp)
mod_func
Returns
true
if the contents of filesa
andb
are identical,false
otherwise. -
.compare_stream(a, b)
mod_func
Returns
true
if the contents of streamsa
andb
are identical,false
otherwise. -
.copy(src, dest, preserve: nil, noop: nil, verbose: nil)
mod_func
Alias for #cp.
-
.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
mod_func
Recursively copies files from
src
todest
. -
.copy_file(src, dest, preserve = false, dereference = true)
mod_func
Copies file from
src
todest
, which should not be directories. -
.copy_stream(src, dest)
mod_func
Copies IO stream
src
to IO streamdest
via{IO.copy_stream
}. -
.cp(src, dest, preserve: nil, noop: nil, verbose: nil)
(also: #copy)
mod_func
Copies files.
-
.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
mod_func
Creates hard links.
-
.cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil)
mod_func
Recursively copies files.
-
.getwd
mod_func
Alias for #pwd.
-
.identical?(a, b)
mod_func
Alias for #compare_file.
-
.install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil)
mod_func
Copies a file entry.
-
.link(src, dest, force: nil, noop: nil, verbose: nil)
mod_func
Alias for #ln.
-
.link_entry(src, dest, dereference_root = false, remove_destination = false)
mod_func
Creates hard links; returns
nil
. -
.ln(src, dest, force: nil, noop: nil, verbose: nil)
(also: #link)
mod_func
Creates hard links.
-
.ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
(also: #symlink)
mod_func
Creates symbolic links.
-
.ln_sf(src, dest, noop: nil, verbose: nil)
mod_func
Like .ln_s, but always with keyword argument
force: true
given. -
.ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
mod_func
Like .ln_s, but create links relative to
dest
. -
.makedirs(list, mode: nil, noop: nil, verbose: nil)
mod_func
Alias for #mkdir_p.
-
.mkdir(list, mode: nil, noop: nil, verbose: nil)
mod_func
Creates directories at the paths in the given
list
(a single path or an array of paths); returnslist
if it is an array,[list]
otherwise. -
.mkdir_p(list, mode: nil, noop: nil, verbose: nil)
(also: #mkpath, #makedirs)
mod_func
Creates directories at the paths in the given
list
(a single path or an array of paths), also creating ancestor directories as needed; returnslist
if it is an array,[list]
otherwise. -
.mkpath(list, mode: nil, noop: nil, verbose: nil)
mod_func
Alias for #mkdir_p.
-
.move(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
mod_func
Alias for #mv.
-
.mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
(also: #move)
mod_func
Moves entries.
-
.pwd
(also: #getwd)
mod_func
Returns a string containing the path to the current directory:
-
.remove(list, force: nil, noop: nil, verbose: nil)
mod_func
Alias for #rm.
-
.remove_dir(path, force = false)
mod_func
Recursively removes the directory entry given by
path
, which should be the entry for a regular file, a symbolic link, or a directory. -
.remove_entry(path, force = false)
mod_func
Removes the entry given by
path
, which should be the entry for a regular file, a symbolic link, or a directory. -
.remove_entry_secure(path, force = false)
mod_func
Securely removes the entry given by
path
, which should be the entry for a regular file, a symbolic link, or a directory. -
.remove_file(path, force = false)
mod_func
Removes the file entry given by
path
, which should be the entry for a regular file or a symbolic link. -
.rm(list, force: nil, noop: nil, verbose: nil)
(also: #remove)
mod_func
Removes entries at the paths in the given
list
(a single path or an array of paths) returnslist
, if it is an array,[list]
otherwise. -
.rm_f(list, noop: nil, verbose: nil)
(also: #safe_unlink)
mod_func
Equivalent to:
-
.rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
mod_func
Removes entries at the paths in the given
list
(a single path or an array of paths); returnslist
, if it is an array,[list]
otherwise. -
.rm_rf(list, noop: nil, verbose: nil, secure: nil)
(also: #rmtree)
mod_func
Equivalent to:
-
.rmdir(list, parents: nil, noop: nil, verbose: nil)
mod_func
Removes directories at the paths in the given
list
(a single path or an array of paths); returnslist
, if it is an array,[list]
otherwise. -
.rmtree(list, noop: nil, verbose: nil, secure: nil)
mod_func
Alias for #rm_rf.
-
.safe_unlink(list, noop: nil, verbose: nil)
mod_func
Alias for #rm_f.
-
.symlink(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
mod_func
Alias for #ln_s.
-
.touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
mod_func
Updates modification times (mtime) and access times (atime) of the entries given by the paths in
list
(a single path or an array of paths); returnslist
if it is an array,[list]
otherwise. -
.uptodate?(new, old_list) ⇒ Boolean
mod_func
Returns
true
if the file at pathnew
is newer than all the files at paths in arrayold_list
;false
otherwise. - .private_module_function(name) Internal use only
StreamUtils_
- Extended
Instance Attribute Summary
- #fu_have_symlink? ⇒ Boolean readonly Internal use only
Instance Method Summary
- #fu_clean_components(*comp)
- #fu_split_path(path)
-
#fu_starting_path?(path)
See additional method definition at line 2546.
- #apply_mask(mode, user_mask, op, mode_mask) Internal use only
- #fu_each_src_dest(src, dest) Internal use only
- #fu_each_src_dest0(src, dest, target_directory = true) Internal use only
- #fu_get_gid(group) Internal use only
- #fu_get_uid(user) Internal use only
-
#fu_list(arg)
Internal use only
class
Entry_
. - #fu_mkdir(path, mode) Internal use only
- #fu_mode(mode, path) Internal use only
- #fu_output_message(msg) Internal use only
- #fu_relative_components_from(target, base) Internal use only
- #fu_same?(a, b) ⇒ Boolean Internal use only
- #fu_stat_identical_entry?(a, b) ⇒ Boolean Internal use only
- #mode_to_s(mode) Internal use only
- #remove_trailing_slash(dir) Internal use only
- #symbolic_modes_to_i(mode_sym, path) Internal use only
- #user_mask(target) Internal use only
StreamUtils_
- Included
Class Method Details
.cd(dir, verbose: nil, &block) (mod_func) Also known as: #chdir
Changes the working directory to the given dir
, which should be interpretable as a path
:
With no block given, changes the current directory to the directory at dir
; returns zero:
FileUtils.pwd # => "/rdoc/fileutils"
FileUtils.cd('..')
FileUtils.pwd # => "/rdoc"
FileUtils.cd('fileutils')
With a block given, changes the current directory to the directory at dir
, calls the block with argument dir
, and restores the original current directory; returns the block’s value:
FileUtils.pwd # => "/rdoc/fileutils"
FileUtils.cd('..') { |arg| [arg, FileUtils.pwd] } # => ["..", "/rdoc"]
FileUtils.pwd # => "/rdoc/fileutils"
Keyword arguments:
-
verbose: true
- prints an equivalent command:FileUtils.cd('..') FileUtils.cd('fileutils')
Output:
cd .. cd fileutils
Related: .pwd.
# File 'lib/fileutils.rb', line 238
def cd(dir, verbose: nil, &block) # :yield: dir "cd #{dir}" if verbose result = Dir.chdir(dir, &block) 'cd -' if verbose and block result end
.chdir(dir, verbose: nil, &block) (mod_func)
Alias for #cd.
# File 'lib/fileutils.rb', line 246
alias chdir cd
.chmod(mode, list, noop: nil, verbose: nil) (mod_func)
Changes permissions on the entries at the paths given in list
(a single path or an array of paths) to the permissions given by mode
; returns list
if it is an array, [list]
otherwise:
-
Modifies each entry that is a regular file using
File.chmod
. -
Modifies each entry that is a symbolic link using
File.lchmod
.
Argument list
or its elements should be interpretable as paths
.
Argument mode
may be either an integer or a string:
-
Integer
mode
: represents the permission bits to be set:FileUtils.chmod(0755, 'src0.txt') FileUtils.chmod(0644, ['src0.txt', 'src0.dat'])
-
String
mode
: represents the permissions to be set:The string is of the form
[targets][[operator][perms[,perms]]
, where:-
targets
may be any combination of these letters:-
'u'
: permissions apply to the file’s owner. -
'g'
: permissions apply to users in the file’s group. -
'o'
: permissions apply to other users not in the file’s group. -
'a'
(the default): permissions apply to all users.
-
-
operator
may be one of these letters:-
'+'
: adds permissions. -
'-'
: removes permissions. -
'='
: sets (replaces) permissions.
-
-
perms
(may be repeated, with separating commas) may be any combination of these letters:-
'r'
: Read. -
'w'
: Write. -
'x'
: Execute (search, for a directory). -
'X'
: Search (for a directories only; must be used with'+'
) -
's'
: Uid or gid. -
't'
: Sticky bit.
-
Examples:
FileUtils.chmod('u=wrx,go=rx', 'src1.txt') FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby')
-
Keyword arguments:
-
noop: true
- does not change permissions; returnsnil
. -
verbose: true
- prints an equivalent command:FileUtils.chmod(0755, 'src0.txt', noop: true, verbose: true) FileUtils.chmod(0644, ['src0.txt', 'src0.dat'], noop: true, verbose: true) FileUtils.chmod('u=wrx,go=rx', 'src1.txt', noop: true, verbose: true) FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby', noop: true, verbose: true)
Output:
chmod 755 src0.txt chmod 644 src0.txt src0.dat chmod u=wrx,go=rx src1.txt chmod u=wrx,go=rx /usr/bin/ruby
Related: .chmod_R.
.chmod_R(mode, list, noop: nil, verbose: nil, force: nil) (mod_func)
Like .chmod, but changes permissions recursively.
# File 'lib/fileutils.rb', line 1815
def chmod_R(mode, list, noop: nil, verbose: nil, force: nil) list = fu_list(list) sprintf('chmod -R%s %s %s', (force ? 'f' : ''), mode_to_s(mode), list.join(' ')) if verbose return if noop list.each do |root| Entry_.new(root).traverse do |ent| begin ent.chmod(fu_mode(mode, ent.path)) rescue raise unless force end end end end
.chown(user, group, list, noop: nil, verbose: nil) (mod_func)
Changes the owner and group on the entries at the paths given in list
(a single path or an array of paths) to the given user
and group
; returns list
if it is an array, [list]
otherwise:
-
Modifies each entry that is a regular file using
File.chown
. -
Modifies each entry that is a symbolic link using
File.lchown
.
Argument list
or its elements should be interpretable as paths
.
User and group:
-
Argument
user
may be a user name or a user id; ifnil
or-1
, the user is not changed. -
Argument
group
may be a group name or a group id; ifnil
or-1
, the group is not changed. -
The user must be a member of the group.
Examples:
# One path.
# User and group as string names.
File.stat('src0.txt').uid # => 1004
File.stat('src0.txt').gid # => 1004
FileUtils.chown('user2', 'group1', 'src0.txt')
File.stat('src0.txt').uid # => 1006
File.stat('src0.txt').gid # => 1005
# User and group as uid and gid.
FileUtils.chown(1004, 1004, 'src0.txt')
File.stat('src0.txt').uid # => 1004
File.stat('src0.txt').gid # => 1004
# Array of paths.
FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'])
# Directory (not recursive).
FileUtils.chown('user2', 'group1', '.')
Keyword arguments:
-
noop: true
- does not change permissions; returnsnil
. -
verbose: true
- prints an equivalent command:FileUtils.chown('user2', 'group1', 'src0.txt', noop: true, verbose: true) FileUtils.chown(1004, 1004, 'src0.txt', noop: true, verbose: true) FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'], noop: true, verbose: true) FileUtils.chown('user2', 'group1', path, noop: true, verbose: true) FileUtils.chown('user2', 'group1', '.', noop: true, verbose: true)
Output:
chown user2:group1 src0.txt chown 1004:1004 src0.txt chown 1006:1005 src0.txt src0.dat chown user2:group1 src0.txt chown user2:group1 .
Related: .chown_R.
# File 'lib/fileutils.rb', line 1896
def chown(user, group, list, noop: nil, verbose: nil) list = fu_list(list) sprintf('chown %s %s', (group ? "#{user}:#{group}" : user || ':'), list.join(' ')) if verbose return if noop uid = fu_get_uid(user) gid = fu_get_gid(group) list.each do |path| Entry_.new(path).chown uid, gid end end
.chown_R(user, group, list, noop: nil, verbose: nil, force: nil) (mod_func)
Like .chown, but changes owner and group recursively.
# File 'lib/fileutils.rb', line 1912
def chown_R(user, group, list, noop: nil, verbose: nil, force: nil) list = fu_list(list) sprintf('chown -R%s %s %s', (force ? 'f' : ''), (group ? "#{user}:#{group}" : user || ':'), list.join(' ')) if verbose return if noop uid = fu_get_uid(user) gid = fu_get_gid(group) list.each do |root| Entry_.new(root).traverse do |ent| begin ent.chown uid, gid rescue raise unless force end end end end
.cmp(a, b) (mod_func)
Alias for #compare_file.
# File 'lib/fileutils.rb', line 1518
alias cmp compare_file
.collect_method(opt)
Returns an array of the string method names of the methods that accept the given keyword option opt
; the argument must be a symbol:
FileUtils.collect_method(:preserve) # => ["cp", "copy", "cp_r", "install"]
.commands
Returns an array of the string names of FileUtils methods that accept one or more keyword arguments:
FileUtils.commands.sort.take(3) # => ["cd", "chdir", "chmod"]
# File 'lib/fileutils.rb', line 2570
def self.commands OPT_TABLE.keys end
.compare_file(a, b) (mod_func) Also known as: #identical?, #cmp
Returns true
if the contents of files a
and b
are identical, false
otherwise.
Arguments a
and b
should be interpretable as a path
.
.identical? and .cmp are aliases for compare_file
.
Related: .compare_stream.
# File 'lib/fileutils.rb', line 1507
def compare_file(a, b) return false unless File.size(a) == File.size(b) File.open(a, 'rb') {|fa| File.open(b, 'rb') {|fb| return compare_stream(fa, fb) } } end
.compare_stream(a, b) (mod_func)
Returns true
if the contents of streams a
and b
are identical, false
otherwise.
Arguments a
and b
should be interpretable as a path
.
Related: .compare_file.
# File 'lib/fileutils.rb', line 1530
def compare_stream(a, b) bsize = fu_stream_blksize(a, b) sa = String.new(capacity: bsize) sb = String.new(capacity: bsize) begin a.read(bsize, sa) b.read(bsize, sb) return true if sa.empty? && sb.empty? end while sa == sb false end
.copy(src, dest, preserve: nil, noop: nil, verbose: nil) (mod_func)
Alias for #cp.
# File 'lib/fileutils.rb', line 882
alias copy cp
.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) (mod_func)
Recursively copies files from src
to dest
.
Arguments src
and dest
should be interpretable as paths
.
If src
is the path to a file, copies src
to dest
:
FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.copy_entry('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true
If src
is a directory, recursively copies src
to dest
:
tree('src1')
# => src1
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
FileUtils.copy_entry('src1', 'dest1')
tree('dest1')
# => dest1
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
The recursive copying preserves file types for regular files, directories, and symbolic links; other file types (FIFO streams, device files, etc.) are not supported.
Keyword arguments:
-
dereference_root: true
- ifsrc
is a symbolic link, follows the link. -
preserve: true
- preserves file times. -
remove_destination: true
- removesdest
before copying files.
Related: methods for copying
.
# File 'lib/fileutils.rb', line 1040
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) if dereference_root src = File.realpath(src) end Entry_.new(src, nil, false).wrap_traverse(proc do |ent| destent = Entry_.new(dest, ent.rel, false) File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path)) ent.copy destent.path end, proc do |ent| destent = Entry_.new(dest, ent.rel, false) ent. destent.path if preserve end) end
.copy_file(src, dest, preserve = false, dereference = true) (mod_func)
Copies file from src
to dest
, which should not be directories.
Arguments src
and dest
should be interpretable as paths
.
Examples:
FileUtils.touch('src0.txt')
FileUtils.copy_file('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true
Keyword arguments:
-
dereference: false
- ifsrc
is a symbolic link, does not follow the link. -
preserve: true
- preserves file times. -
remove_destination: true
- removesdest
before copying files.
Related: methods for copying
.
.copy_stream(src, dest) (mod_func)
Copies IO stream src
to IO stream dest
via {IO.copy_stream
}.
Related: methods for copying
.
# File 'lib/fileutils.rb', line 1088
def copy_stream(src, dest) IO.copy_stream(src, dest) end
.cp(src, dest, preserve: nil, noop: nil, verbose: nil) (mod_func) Also known as: #copy
Copies files.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths
.
If src
is the path to a file and dest
is not the path to a directory, copies src
to dest
:
FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true
If src
is the path to a file and dest
is the path to a directory, copies src
to dest/src
:
FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true
If src
is an array of paths to files and dest
is the path to a directory, copies from each src
to dest
:
src_file_paths = ['src2.txt', 'src2.dat']
FileUtils.touch(src_file_paths)
FileUtils.mkdir('dest2')
FileUtils.cp(src_file_paths, 'dest2')
File.file?('dest2/src2.txt') # => true
File.file?('dest2/src2.dat') # => true
Keyword arguments:
-
preserve: true
- preserves file times. -
noop: true
- does not copy files. -
verbose: true
- prints an equivalent command:FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true) FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true) FileUtils.cp(src_file_paths, 'dest2', noop: true, verbose: true)
Output:
cp src0.txt dest0.txt cp src1.txt dest1 cp src2.txt src2.dat dest2
Raises an exception if src
is a directory.
Related: methods for copying
.
# File 'lib/fileutils.rb', line 873
def cp(src, dest, preserve: nil, noop: nil, verbose: nil) "cp#{preserve ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if verbose return if noop fu_each_src_dest(src, dest) do |s, d| copy_file s, d, preserve end end
.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false) (mod_func)
Creates hard links.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths
.
If src
is the path to a directory and dest
does not exist, creates links dest
and descendents pointing to src
and its descendents:
tree('src0')
# => src0
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
File.exist?('dest0') # => false
FileUtils.cp_lr('src0', 'dest0')
tree('dest0')
# => dest0
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
If src
and dest
are both paths to directories, creates links dest/src
and descendents pointing to src
and its descendents:
tree('src1')
# => src1
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
FileUtils.mkdir('dest1')
FileUtils.cp_lr('src1', 'dest1')
tree('dest1')
# => dest1
# `-- src1
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
If src
is an array of paths to entries and dest
is the path to a directory, for each path filepath
in src
, creates a link at dest/filepath
pointing to that path:
tree('src2')
# => src2
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
FileUtils.mkdir('dest2')
FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2')
tree('dest2')
# => dest2
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
Keyword arguments:
-
dereference_root: false
- ifsrc
is a symbolic link, does not dereference it. -
noop: true
- does not create links. -
remove_destination: true
- removesdest
before creating links. -
verbose: true
- prints an equivalent command:FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true) FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true) FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2', noop: true, verbose: true)
Output:
cp -lr src0 dest0 cp -lr src1 dest1 cp -lr src2/sub0 src2/sub1 dest2
Raises an exception if dest
is the path to an existing file or directory and keyword argument remove_destination: true
is not given.
Related: methods for copying
.
# File 'lib/fileutils.rb', line 627
def cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false) "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose return if noop fu_each_src_dest(src, dest) do |s, d| link_entry s, d, dereference_root, remove_destination end end
.cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) (mod_func)
Recursively copies files.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths
.
The mode, owner, and group are retained in the copy; to change those, use .install instead.
If src
is the path to a file and dest
is not the path to a directory, copies src
to dest
:
FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp_r('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true
If src
is the path to a file and dest
is the path to a directory, copies src
to dest/src
:
FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp_r('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true
If src
is the path to a directory and dest
does not exist, recursively copies src
to dest
:
tree('src2')
# => src2
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
FileUtils.exist?('dest2') # => false
FileUtils.cp_r('src2', 'dest2')
tree('dest2')
# => dest2
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
If src
and dest
are paths to directories, recursively copies src
to dest/src
:
tree('src3')
# => src3
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
FileUtils.mkdir('dest3')
FileUtils.cp_r('src3', 'dest3')
tree('dest3')
# => dest3
# `-- src3
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
If src
is an array of paths and dest
is a directory, recursively copies from each path in src
to dest
; the paths in src
may point to files and/or directories.
Keyword arguments:
-
dereference_root: false
- ifsrc
is a symbolic link, does not dereference it. -
noop: true
- does not copy files. -
preserve: true
- preserves file times. -
remove_destination: true
- removesdest
before copying files. -
verbose: true
- prints an equivalent command:FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true) FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true) FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true) FileUtils.cp_r('src3', 'dest3', noop: true, verbose: true)
Output:
cp -r src0.txt dest0.txt cp -r src1.txt dest1 cp -r src2 dest2 cp -r src3 dest3
Raises an exception of src
is the path to a directory and dest
is the path to a file.
Related: methods for copying
.
# File 'lib/fileutils.rb', line 985
def cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) "cp -r#{preserve ? 'p' : ''}#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose return if noop fu_each_src_dest(src, dest) do |s, d| copy_entry s, d, preserve, dereference_root, remove_destination end end
.getwd (mod_func)
Alias for #pwd.
# File 'lib/fileutils.rb', line 202
alias getwd pwd
.have_option?(mid, opt) ⇒ Boolean
Returns true
if method mid
accepts the given option opt
, false
otherwise; the arguments may be strings or symbols:
FileUtils.have_option?(:chmod, :noop) # => true
FileUtils.have_option?('chmod', 'secure') # => false
# File 'lib/fileutils.rb', line 2588
def self.have_option?(mid, opt) li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}" li.include?(opt) end
.identical?(a, b) (mod_func)
Alias for #compare_file.
# File 'lib/fileutils.rb', line 1517
alias identical? compare_file
.install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) (mod_func)
Copies a file entry. See install(1).
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths
;
If the entry at dest
does not exist, copies from src
to dest
:
File.read('src0.txt') # => "aaa\n"
File.exist?('dest0.txt') # => false
FileUtils.install('src0.txt', 'dest0.txt')
File.read('dest0.txt') # => "aaa\n"
If dest
is a file entry, copies from src
to dest
, overwriting:
File.read('src1.txt') # => "aaa\n"
File.read('dest1.txt') # => "bbb\n"
FileUtils.install('src1.txt', 'dest1.txt')
File.read('dest1.txt') # => "aaa\n"
If dest
is a directory entry, copies from src
to dest/src
, overwriting if necessary:
File.read('src2.txt') # => "aaa\n"
File.read('dest2/src2.txt') # => "bbb\n"
FileUtils.install('src2.txt', 'dest2')
File.read('dest2/src2.txt') # => "aaa\n"
If src
is an array of paths and dest
points to a directory, copies each path path
in src
to dest/path
:
File.file?('src3.txt') # => true
File.file?('src3.dat') # => true
FileUtils.mkdir('dest3')
FileUtils.install(['src3.txt', 'src3.dat'], 'dest3')
File.file?('dest3/src3.txt') # => true
File.file?('dest3/src3.dat') # => true
Keyword arguments:
-
group: group
- changes the group if notnil
, usingFile.chown
. -
mode: permissions
- changes the permissions. usingFile.chmod
. -
noop: true
- does not copy entries; returnsnil
. -
owner: owner
- changes the owner if notnil
, usingFile.chown
. -
preserve: true
- preserve timestamps usingFile.utime
. -
verbose: true
- prints an equivalent command:FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true) FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true) FileUtils.install('src2.txt', 'dest2', noop: true, verbose: true)
Output:
install -c src0.txt dest0.txt install -c src1.txt dest1.txt install -c src2.txt dest2
Related: methods for copying
.
# File 'lib/fileutils.rb', line 1609
def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) if verbose msg = +"install -c" msg << ' -p' if preserve msg << ' -m ' << mode_to_s(mode) if mode msg << " -o #{owner}" if owner msg << " -g #{group}" if group msg << ' ' << [src,dest].flatten.join(' ') msg end return if noop uid = fu_get_uid(owner) gid = fu_get_gid(group) fu_each_src_dest(src, dest) do |s, d| st = File.stat(s) unless File.exist?(d) and compare_file(s, d) remove_file d, true if d.end_with?('/') mkdir_p d copy_file s, d + File.basename(s) else mkdir_p File. ('..', d) copy_file s, d end File.utime st.atime, st.mtime, d if preserve File.chmod fu_mode(mode, st), d if mode File.chown uid, gid, d if uid or gid end end end
.link(src, dest, force: nil, noop: nil, verbose: nil) (mod_func)
Alias for #ln.
# File 'lib/fileutils.rb', line 526
alias link ln
.link_entry(src, dest, dereference_root = false, remove_destination = false) (mod_func)
Creates hard links; returns nil
.
Arguments src
and dest
should be interpretable as paths
.
If src
is the path to a file and dest
does not exist, creates a hard link at dest
pointing to src
:
FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.link_entry('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true
If src
is the path to a directory and dest
does not exist, recursively creates hard links at dest
pointing to paths in src
:
FileUtils.mkdir_p(['src1/dir0', 'src1/dir1'])
src_file_paths = [
'src1/dir0/t0.txt',
'src1/dir0/t1.txt',
'src1/dir1/t2.txt',
'src1/dir1/t3.txt',
]
FileUtils.touch(src_file_paths)
File.directory?('dest1') # => true
FileUtils.link_entry('src1', 'dest1')
File.file?('dest1/dir0/t0.txt') # => true
File.file?('dest1/dir0/t1.txt') # => true
File.file?('dest1/dir1/t2.txt') # => true
File.file?('dest1/dir1/t3.txt') # => true
Keyword arguments:
-
dereference_root: true
- dereferencessrc
if it is a symbolic link. -
remove_destination: true
- removesdest
before creating links.
Raises an exception if dest
is the path to an existing file or directory and keyword argument remove_destination: true
is not given.
Related: .ln (has different options).
# File 'lib/fileutils.rb', line 812
def link_entry(src, dest, dereference_root = false, remove_destination = false) Entry_.new(src, nil, dereference_root).traverse do |ent| destent = Entry_.new(dest, ent.rel, false) File.unlink destent.path if remove_destination && File.file?(destent.path) ent.link destent.path end end
.ln(src, dest, force: nil, noop: nil, verbose: nil) (mod_func) Also known as: #link
Creates hard links.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths
.
When src
is the path to an existing file and dest
is the path to a non-existent file, creates a hard link at dest
pointing to src
; returns zero:
Dir.children('tmp0/') # => ["t.txt"]
Dir.children('tmp1/') # => []
FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk') # => 0
Dir.children('tmp1/') # => ["t.lnk"]
When src
is the path to an existing file and dest
is the path to an existing directory, creates a hard link at dest/src
pointing to src
; returns zero:
Dir.children('tmp2') # => ["t.dat"]
Dir.children('tmp3') # => []
FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0
Dir.children('tmp3') # => ["t.dat"]
When src
is an array of paths to existing files and dest
is the path to an existing directory, then for each path target
in src
, creates a hard link at dest/target
pointing to target
; returns src
:
Dir.children('tmp4/') # => []
FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/') # => ["tmp0/t.txt", "tmp2/t.dat"]
Dir.children('tmp4/') # => ["t.dat", "t.txt"]
Keyword arguments:
-
force: true
- overwritesdest
if it exists. -
noop: true
- does not create links. -
verbose: true
- prints an equivalent command:FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true) FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true) FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/', verbose: true)
Output:
ln tmp0/t.txt tmp1/t.lnk ln tmp2/t.dat tmp3 ln tmp0/t.txt tmp2/t.dat tmp4/
Raises an exception if dest
is the path to an existing file and keyword argument force
is not true
.
Related: .link_entry (has different options).
# File 'lib/fileutils.rb', line 516
def ln(src, dest, force: nil, noop: nil, verbose: nil) "ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose return if noop fu_each_src_dest0(src, dest) do |s,d| remove_file d, true if force File.link s, d end end
.ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil) (mod_func) Also known as: #symlink
Creates symbolic links.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths
.
If src
is the path to an existing file:
-
When
dest
is the path to a non-existent file, creates a symbolic link atdest
pointing tosrc
:FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false FileUtils.ln_s('src0.txt', 'dest0.txt') File.symlink?('dest0.txt') # => true
-
When
dest
is the path to an existing file, creates a symbolic link atdest
pointing tosrc
if and only if keyword argumentforce: true
is given (raises an exception otherwise):FileUtils.touch('src1.txt') FileUtils.touch('dest1.txt') FileUtils.ln_s('src1.txt', 'dest1.txt', force: true) FileTest.symlink?('dest1.txt') # => true FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
If dest
is the path to a directory, creates a symbolic link at dest/src
pointing to src
:
FileUtils.touch('src2.txt')
FileUtils.mkdir('destdir2')
FileUtils.ln_s('src2.txt', 'destdir2')
File.symlink?('destdir2/src2.txt') # => true
If src
is an array of paths to existing files and dest
is a directory, for each child child
in src
creates a symbolic link dest/child
pointing to child
:
FileUtils.mkdir('srcdir3')
FileUtils.touch('srcdir3/src0.txt')
FileUtils.touch('srcdir3/src1.txt')
FileUtils.mkdir('destdir3')
FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3')
File.symlink?('destdir3/src0.txt') # => true
File.symlink?('destdir3/src1.txt') # => true
Keyword arguments:
-
force: true
- overwritesdest
if it exists. -
relative: false
- create links relative todest
. -
noop: true
- does not create links. -
verbose: true
- prints an equivalent command:FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true) FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true) FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true) FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3', noop: true, verbose: true)
Output:
ln -s src0.txt dest0.txt ln -s src1.txt destdir1 ln -sf src2.txt dest2.txt ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3
Related: .ln_sf.
# File 'lib/fileutils.rb', line 706
def ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil) if relative return ln_sr(src, dest, force: force, noop: noop, verbose: verbose) end "ln -s#{force ? 'f' : ''} #{[src,dest].flatten.join ' '}" if verbose return if noop fu_each_src_dest0(src, dest) do |s,d| remove_file d, true if force File.symlink s, d end end
.ln_sf(src, dest, noop: nil, verbose: nil) (mod_func)
Like .ln_s, but always with keyword argument force: true
given.
# File 'lib/fileutils.rb', line 724
def ln_sf(src, dest, noop: nil, verbose: nil) ln_s src, dest, force: true, noop: noop, verbose: verbose end
.ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil) (mod_func)
Like .ln_s, but create links relative to dest
.
# File 'lib/fileutils.rb', line 731
def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil) = "#{force ? 'f' : ''}#{target_directory ? '' : 'T'}" dest = File.path(dest) srcs = Array(src) link = proc do |s, target_dir_p = true| s = File.path(s) if target_dir_p d = File.join(destdirs = dest, File.basename(s)) else destdirs = File.dirname(d = dest) end destdirs = fu_split_path(File.realpath(destdirs)) if fu_starting_path?(s) srcdirs = fu_split_path((File.realdirpath(s) rescue File. (s))) base = fu_relative_components_from(srcdirs, destdirs) s = File.join(*base) else srcdirs = fu_clean_components(*fu_split_path(s)) base = fu_relative_components_from(fu_split_path(Dir.pwd), destdirs) while srcdirs.first&. == ".." and base.last&.!=("..") and !fu_starting_path?(base.last) srcdirs.shift base.pop end s = File.join(*base, *srcdirs) end "ln -s#{} #{s} #{d}" if verbose next if noop remove_file d, true if force File.symlink s, d end case srcs.size when 0 when 1 link[srcs[0], target_directory && File.directory?(dest)] else srcs.each(&link) end end
.makedirs(list, mode: nil, noop: nil, verbose: nil) (mod_func)
Alias for #mkdir_p.
# File 'lib/fileutils.rb', line 392
alias makedirs mkdir_p
.mkdir(list, mode: nil, noop: nil, verbose: nil) (mod_func)
Creates directories at the paths in the given list
(a single path or an array of paths); returns list
if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths
.
With no keyword arguments, creates a directory at each path
in list
by calling: Dir.mkdir(path, mode)
; see {Dir.mkdir
}:
FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"]
FileUtils.mkdir('tmp4') # => ["tmp4"]
Keyword arguments:
-
mode: mode
- also callsFile.chmod(mode, path)
; seeFile.chmod
. -
noop: true
- does not create directories. -
verbose: true
- prints an equivalent command:FileUtils.mkdir(%w[tmp0 tmp1], verbose: true) FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
Output:
mkdir tmp0 tmp1 mkdir -m 700 tmp2 tmp3
Raises an exception if any path points to an existing file or directory, or if for any reason a directory cannot be created.
Related: .mkdir_p.
.mkdir_p(list, mode: nil, noop: nil, verbose: nil) (mod_func) Also known as: #mkpath, #makedirs
Creates directories at the paths in the given list
(a single path or an array of paths), also creating ancestor directories as needed; returns list
if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths
.
With no keyword arguments, creates a directory at each path
in list
, along with any needed ancestor directories, by calling: Dir.mkdir(path, mode)
; see {Dir.mkdir
}:
FileUtils.mkdir_p(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
FileUtils.mkdir_p('tmp4/tmp5') # => ["tmp4/tmp5"]
Keyword arguments:
-
mode: mode
- also callsFile.chmod(mode, path)
; seeFile.chmod
. -
noop: true
- does not create directories. -
verbose: true
- prints an equivalent command:FileUtils.mkdir_p(%w[tmp0 tmp1], verbose: true) FileUtils.mkdir_p(%w[tmp2 tmp3], mode: 0700, verbose: true)
Output:
mkdir -p tmp0 tmp1 mkdir -p -m 700 tmp2 tmp3
Raises an exception if for any reason a directory cannot be created.
.mkpath and .makedirs are aliases for mkdir_p
.
Related: .mkdir.
# File 'lib/fileutils.rb', line 365
def mkdir_p(list, mode: nil, noop: nil, verbose: nil) list = fu_list(list) "mkdir -p #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose return *list if noop list.each do |item| path = remove_trailing_slash(item) stack = [] until File.directory?(path) || File.dirname(path) == path stack.push path path = File.dirname(path) end stack.reverse_each do |dir| begin fu_mkdir dir, mode rescue SystemCallError raise unless File.directory?(dir) end end end return *list end
.mkpath(list, mode: nil, noop: nil, verbose: nil) (mod_func)
Alias for #mkdir_p.
# File 'lib/fileutils.rb', line 391
alias mkpath mkdir_p
.move(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) (mod_func)
Alias for #mv.
# File 'lib/fileutils.rb', line 1186
alias move mv
.mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) (mod_func) Also known as: #move
Moves entries.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths
.
If src
and dest
are on different file systems, first copies, then removes src
.
May cause a local vulnerability if not called with keyword argument secure: true
; see Avoiding the TOCTTOU Vulnerability
.
If src
is the path to a single file or directory and dest
does not exist, moves src
to dest
:
tree('src0')
# => src0
# |-- src0.txt
# `-- src1.txt
File.exist?('dest0') # => false
FileUtils.mv('src0', 'dest0')
File.exist?('src0') # => false
tree('dest0')
# => dest0
# |-- src0.txt
# `-- src1.txt
If src
is an array of paths to files and directories and dest
is the path to a directory, copies from each path in the array to dest
:
File.file?('src1.txt') # => true
tree('src1')
# => src1
# |-- src.dat
# `-- src.txt
Dir.empty?('dest1') # => true
FileUtils.mv(['src1.txt', 'src1'], 'dest1')
tree('dest1')
# => dest1
# |-- src1
# | |-- src.dat
# | `-- src.txt
# `-- src1.txt
Keyword arguments:
-
force: true
- if the move includes removingsrc
(that is, ifsrc
anddest
are on different file systems), ignores raised exceptions of StandardError and its descendants. -
noop: true
- does not move files. -
secure: true
- removessrc
securely; see details at FileUtils.remove_entry_secure. -
verbose: true
- prints an equivalent command:FileUtils.mv('src0', 'dest0', noop: true, verbose: true) FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
Output:
mv src0 dest0 mv src1.txt src1 dest1
# File 'lib/fileutils.rb', line 1157
def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose return if noop fu_each_src_dest(src, dest) do |s, d| destent = Entry_.new(d, nil, true) begin if destent.exist? if destent.directory? raise Errno::EEXIST, d end end begin File.rename s, d rescue Errno::EXDEV, Errno::EPERM # move from unencrypted to encrypted dir (ext4) copy_entry s, d, true if secure remove_entry_secure s, force else remove_entry s, force end end rescue SystemCallError raise unless force end end end
.options
Returns an array of the string keyword names:
FileUtils. .take(3) # => ["noop", "verbose", "force"]
# File 'lib/fileutils.rb', line 2578
def self. OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s } end
.options_of(mid)
Returns an array of the string keyword name for method mid
; the argument may be a string or a symbol:
FileUtils. (:rm) # => ["force", "noop", "verbose"]
FileUtils. ('mv') # => ["force", "noop", "verbose", "secure"]
# File 'lib/fileutils.rb', line 2599
def self. (mid) OPT_TABLE[mid.to_s].map {|sym| sym.to_s } end
.private_module_function(name)
# File 'lib/fileutils.rb', line 185
def self.private_module_function(name) #:nodoc: module_function name private_class_method name end
.pwd (mod_func) Also known as: #getwd
Returns a string containing the path to the current directory:
FileUtils.pwd # => "/rdoc/fileutils"
Related: .cd.
# File 'lib/fileutils.rb', line 197
def pwd Dir.pwd end
.remove(list, force: nil, noop: nil, verbose: nil) (mod_func)
Alias for #rm.
# File 'lib/fileutils.rb', line 1227
alias remove rm
.remove_dir(path, force = false) (mod_func)
Recursively removes the directory entry given by path
, which should be the entry for a regular file, a symbolic link, or a directory.
Argument path
should be interpretable as a path
.
Optional argument force
specifies whether to ignore raised exceptions of StandardError and its descendants.
Related: methods for deleting
.
# File 'lib/fileutils.rb', line 1492
def remove_dir(path, force = false) remove_entry path, force # FIXME?? check if it is a directory end
.remove_entry(path, force = false) (mod_func)
Removes the entry given by path
, which should be the entry for a regular file, a symbolic link, or a directory.
Argument path
should be interpretable as a path
.
Optional argument force
specifies whether to ignore raised exceptions of StandardError and its descendants.
Related: .remove_entry_secure.
# File 'lib/fileutils.rb', line 1449
def remove_entry(path, force = false) Entry_.new(path).postorder_traverse do |ent| begin ent.remove rescue raise unless force end end rescue raise unless force end
.remove_entry_secure(path, force = false) (mod_func)
Securely removes the entry given by path
, which should be the entry for a regular file, a symbolic link, or a directory.
Argument path
should be interpretable as a path
.
Avoids a local vulnerability that can exist in certain circumstances; see Avoiding the TOCTTOU Vulnerability
.
Optional argument force
specifies whether to ignore raised exceptions of StandardError and its descendants.
Related: methods for deleting
.
# File 'lib/fileutils.rb', line 1351
def remove_entry_secure(path, force = false) unless fu_have_symlink? remove_entry path, force return end fullpath = File. (path) st = File.lstat(fullpath) unless st.directory? File.unlink fullpath return end # is a directory. parent_st = File.stat(File.dirname(fullpath)) unless parent_st.world_writable? remove_entry path, force return end unless parent_st.sticky? raise ArgumentError, "parent directory is world writable, FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})" end # freeze tree root euid = Process.euid dot_file = fullpath + "/." begin File.open(dot_file) {|f| unless fu_stat_identical_entry?(st, f.stat) # symlink (TOC-to-TOU attack?) File.unlink fullpath return end f.chown euid, -1 f.chmod 0700 } rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs File.lstat(dot_file).tap {|fstat| unless fu_stat_identical_entry?(st, fstat) # symlink (TOC-to-TOU attack?) File.unlink fullpath return end File.chown euid, -1, dot_file File.chmod 0700, dot_file } end unless fu_stat_identical_entry?(st, File.lstat(fullpath)) # TOC-to-TOU attack? File.unlink fullpath return end # ---- tree root is frozen ---- root = Entry_.new(path) root.preorder_traverse do |ent| if ent.directory? ent.chown euid, -1 ent.chmod 0700 end end root.postorder_traverse do |ent| begin ent.remove rescue raise unless force end end rescue raise unless force end
.remove_file(path, force = false) (mod_func)
Removes the file entry given by path
, which should be the entry for a regular file or a symbolic link.
Argument path
should be interpretable as a path
.
Optional argument force
specifies whether to ignore raised exceptions of StandardError and its descendants.
Related: methods for deleting
.
# File 'lib/fileutils.rb', line 1473
def remove_file(path, force = false) Entry_.new(path).remove_file rescue raise unless force end
.rm(list, force: nil, noop: nil, verbose: nil) (mod_func) Also known as: #remove
Removes entries at the paths in the given list
(a single path or an array of paths) returns list
, if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths
.
With no keyword arguments, removes files at the paths given in list
:
FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]
Keyword arguments:
-
force: true
- ignores raised exceptions of StandardError and its descendants. -
noop: true
- does not remove files; returnsnil
. -
verbose: true
- prints an equivalent command:FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
Output:
rm src0.dat src0.txt
Related: methods for deleting
.
# File 'lib/fileutils.rb', line 1216
def rm(list, force: nil, noop: nil, verbose: nil) list = fu_list(list) "rm#{force ? ' -f' : ''} #{list.join ' '}" if verbose return if noop list.each do |path| remove_file path, force end end
.rm_f(list, noop: nil, verbose: nil) (mod_func) Also known as: #safe_unlink
# File 'lib/fileutils.rb', line 1241
def rm_f(list, noop: nil, verbose: nil) rm list, force: true, noop: noop, verbose: verbose end
.rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) (mod_func)
Removes entries at the paths in the given list
(a single path or an array of paths); returns list
, if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths
.
May cause a local vulnerability if not called with keyword argument secure: true
; see Avoiding the TOCTTOU Vulnerability
.
For each file path, removes the file at that path:
FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm_r(['src0.dat', 'src0.txt'])
File.exist?('src0.txt') # => false
File.exist?('src0.dat') # => false
For each directory path, recursively removes files and directories:
tree('src1')
# => src1
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
FileUtils.rm_r('src1')
File.exist?('src1') # => false
Keyword arguments:
-
force: true
- ignores raised exceptions of StandardError and its descendants. -
noop: true
- does not remove entries; returnsnil
. -
secure: true
- removessrc
securely; see details at FileUtils.remove_entry_secure. -
verbose: true
- prints an equivalent command:FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true) FileUtils.rm_r('src1', noop: true, verbose: true)
Output:
rm -r src0.dat src0.txt rm -r src1
Related: methods for deleting
.
# File 'lib/fileutils.rb', line 1299
def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) list = fu_list(list) "rm -r#{force ? 'f' : ''} #{list.join ' '}" if verbose return if noop list.each do |path| if secure remove_entry_secure path, force else remove_entry path, force end end end
.rm_rf(list, noop: nil, verbose: nil, secure: nil) (mod_func) Also known as: #rmtree
Equivalent to:
FileUtils.rm_r(list, force: true, **kwargs)
Argument list
or its elements should be interpretable as paths
.
May cause a local vulnerability if not called with keyword argument secure: true
; see Avoiding the TOCTTOU Vulnerability
.
See .rm_r for keyword arguments.
Related: methods for deleting
.
# File 'lib/fileutils.rb', line 1328
def rm_rf(list, noop: nil, verbose: nil, secure: nil) rm_r list, force: true, noop: noop, verbose: verbose, secure: secure end
.rmdir(list, parents: nil, noop: nil, verbose: nil) (mod_func)
Removes directories at the paths in the given list
(a single path or an array of paths); returns list
, if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths
.
With no keyword arguments, removes the directory at each path
in list
, by calling: Dir.rmdir(path)
; see {Dir.rmdir
}:
FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
FileUtils.rmdir('tmp4/tmp5') # => ["tmp4/tmp5"]
Keyword arguments:
-
parents: true
- removes successive ancestor directories if empty. -
noop: true
- does not remove directories. -
verbose: true
- prints an equivalent command:FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true) FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
Output:
rmdir -p tmp0/tmp1 tmp2/tmp3 rmdir -p tmp4/tmp5
Raises an exception if a directory does not exist or if for any reason a directory cannot be removed.
Related: methods for deleting
.
# File 'lib/fileutils.rb', line 442
def rmdir(list, parents: nil, noop: nil, verbose: nil) list = fu_list(list) "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose return if noop list.each do |dir| Dir.rmdir(dir = remove_trailing_slash(dir)) if parents begin until (parent = File.dirname(dir)) == '.' or parent == dir dir = parent Dir.rmdir(dir) end rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT end end end end
.rmtree(list, noop: nil, verbose: nil, secure: nil) (mod_func)
Alias for #rm_rf.
# File 'lib/fileutils.rb', line 1333
alias rmtree rm_rf
.safe_unlink(list, noop: nil, verbose: nil) (mod_func)
Alias for #rm_f.
# File 'lib/fileutils.rb', line 1246
alias safe_unlink rm_f
.symlink(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil) (mod_func)
Alias for #ln_s.
# File 'lib/fileutils.rb', line 719
alias symlink ln_s
.touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) (mod_func)
Updates modification times (mtime) and access times (atime) of the entries given by the paths in list
(a single path or an array of paths); returns list
if it is an array, [list]
otherwise.
By default, creates an empty file for any path to a non-existent entry; use keyword argument nocreate
to raise an exception instead.
Argument list
or its elements should be interpretable as paths
.
Examples:
# Single path.
f = File.new('src0.txt') # Existing file.
f.atime # => 2022-06-10 11:11:21.200277 -0700
f.mtime # => 2022-06-10 11:11:21.200277 -0700
FileUtils.touch('src0.txt')
f = File.new('src0.txt')
f.atime # => 2022-06-11 08:28:09.8185343 -0700
f.mtime # => 2022-06-11 08:28:09.8185343 -0700
# Array of paths.
FileUtils.touch(['src0.txt', 'src0.dat'])
Keyword arguments:
-
mtime: time
- sets the entry’s mtime to the given time, instead of the current time. -
nocreate: true
- raises an exception if the entry does not exist. -
noop: true
- does not touch entries; returnsnil
. -
verbose: true
- prints an equivalent command:FileUtils.touch('src0.txt', noop: true, verbose: true) FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true) FileUtils.touch(path, noop: true, verbose: true)
Output:
touch src0.txt touch src0.txt src0.dat touch src0.txt
Related: .uptodate?.
# File 'lib/fileutils.rb', line 2006
def touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) list = fu_list(list) t = mtime if verbose "touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}" end return if noop list.each do |path| created = nocreate begin File.utime(t, t, path) rescue Errno::ENOENT raise if created File.open(path, 'a') { ; } created = true retry if t end end end
.uptodate?(new, old_list) ⇒ Boolean
(mod_func)
Returns true
if the file at path new
is newer than all the files at paths in array old_list
; false
otherwise.
Argument new
and the elements of old_list
should be interpretable as paths
:
FileUtils.uptodate?('Rakefile', ['Gemfile', 'README.md']) # => true
FileUtils.uptodate?('Gemfile', ['Rakefile', 'README.md']) # => false
A non-existent file is considered to be infinitely old.
Related: .touch.
# File 'lib/fileutils.rb', line 264
def uptodate?(new, old_list) return false unless File.exist?(new) new_time = File.mtime(new) old_list.each do |old| if File.exist?(old) return false unless new_time > File.mtime(old) end end true end
Instance Attribute Details
#fu_have_symlink? ⇒ Boolean
(readonly)
# File 'lib/fileutils.rb', line 1423
def fu_have_symlink? #:nodoc: File.symlink nil, nil rescue NotImplementedError return false rescue TypeError return true end
Instance Method Details
#apply_mask(mode, user_mask, op, mode_mask)
#fu_clean_components(*comp)
[ GitHub ]# File 'lib/fileutils.rb', line 2527
def fu_clean_components(*comp) comp.shift while comp.first == "." return comp if comp.empty? clean = [comp.shift] path = File.join(*clean, "") # ending with File::SEPARATOR while c = comp.shift if c == ".." and clean.last != ".." and !(fu_have_symlink? && File.symlink?(path)) clean.pop path.chomp!(%r((?<=\A|/)[^/]+/\z), "") else clean << c path << c << "/" end end clean end
#fu_each_src_dest(src, dest)
# File 'lib/fileutils.rb', line 2466
def fu_each_src_dest(src, dest) #:nodoc: fu_each_src_dest0(src, dest) do |s, d| raise ArgumentError, "same file: #{s} and #{d}" if fu_same?(s, d) yield s, d end end
#fu_each_src_dest0(src, dest, target_directory = true)
# File 'lib/fileutils.rb', line 2474
def fu_each_src_dest0(src, dest, target_directory = true) #:nodoc: if tmp = Array.try_convert(src) tmp.each do |s| s = File.path(s) yield s, (target_directory ? File.join(dest, File.basename(s)) : dest) end else src = File.path(src) if target_directory and File.directory?(dest) yield src, File.join(dest, File.basename(src)) else yield src, File.path(dest) end end end
#fu_get_gid(group)
# File 'lib/fileutils.rb', line 1947
def fu_get_gid(group) #:nodoc: return nil unless group case group when Integer group when /\A\d+\z/ group.to_i else require 'etc' Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil end end
#fu_get_uid(user)
# File 'lib/fileutils.rb', line 1933
def fu_get_uid(user) #:nodoc: return nil unless user case user when Integer user when /\A\d+\z/ user.to_i else require 'etc' Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil end end
#fu_list(arg)
class ::FileUtils::Entry_
# File 'lib/fileutils.rb', line 2461
def fu_list(arg) #:nodoc: [arg].flatten.map {|path| File.path(path) } end
#fu_mkdir(path, mode)
# File 'lib/fileutils.rb', line 396
def fu_mkdir(path, mode) #:nodoc: path = remove_trailing_slash(path) if mode Dir.mkdir path, mode File.chmod mode, path else Dir.mkdir path end end
#fu_mode(mode, path)
# File 'lib/fileutils.rb', line 1721
def fu_mode(mode, path) #:nodoc: mode.is_a?(String) ? symbolic_modes_to_i(mode, path) : mode end
#fu_output_message(msg)
# File 'lib/fileutils.rb', line 2496
def (msg) #:nodoc: output = @fileutils_output if defined?(@fileutils_output) output ||= $stdout if defined?(@fileutils_label) msg = @fileutils_label + msg end output.puts msg end
#fu_relative_components_from(target, base)
# File 'lib/fileutils.rb', line 2518
def fu_relative_components_from(target, base) #:nodoc: i = 0 while target[i]&.== base[i] i += 1 end Array.new(base.size-i, '..').concat(target[i..-1]) end
#fu_same?(a, b) ⇒ Boolean
# File 'lib/fileutils.rb', line 2491
def fu_same?(a, b) #:nodoc: File.identical?(a, b) end
#fu_split_path(path)
[ GitHub ]# File 'lib/fileutils.rb', line 2506
def fu_split_path(path) path = File.path(path) list = [] until (parent, base = File.split(path); parent == path or parent == ".") list << base path = parent end list << path list.reverse! end
#fu_starting_path?(path)
See additional method definition at line 2546.
# File 'lib/fileutils.rb', line 2550
def fu_starting_path?(path) path&.start_with?(%r(\w:|/)) end
#fu_stat_identical_entry?(a, b) ⇒ Boolean
# File 'lib/fileutils.rb', line 1432
def fu_stat_identical_entry?(a, b) #:nodoc: a.dev == b.dev and a.ino == b.ino end
#mode_to_s(mode)
# File 'lib/fileutils.rb', line 1726
def mode_to_s(mode) #:nodoc: mode.is_a?(String) ? mode : "%o" % mode end
#remove_trailing_slash(dir)
# File 'lib/fileutils.rb', line 276
def remove_trailing_slash(dir) #:nodoc: dir == '/' ? dir : dir.chomp(?/) end
#symbolic_modes_to_i(mode_sym, path)
# File 'lib/fileutils.rb', line 1672
def symbolic_modes_to_i(mode_sym, path) #:nodoc: path = File.stat(path) unless File::Stat === path mode = path.mode mode_sym.split(/,/).inject(mode & 07777) do |current_mode, clause| target, *actions = clause.split(/([=+-])/) raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty? target = 'a' if target.empty? user_mask = user_mask(target) actions.each_slice(2) do |op, perm| need_apply = op == '=' mode_mask = (perm || '').each_char.inject(0) do |mask, chr| case chr when "r" mask | 0444 when "w" mask | 0222 when "x" mask | 0111 when "X" if path.directory? mask | 0111 else mask end when "s" mask | 06000 when "t" mask | 01000 when "u", "g", "o" if mask.nonzero? current_mode = apply_mask(current_mode, user_mask, op, mask) end need_apply = false copy_mask = user_mask(chr) (current_mode & copy_mask) / (copy_mask & 0111) * (user_mask & 0111) else raise ArgumentError, "invalid `perm' symbol in file mode: #{chr}" end end if mode_mask.nonzero? || need_apply current_mode = apply_mask(current_mode, user_mask, op, mode_mask) end end current_mode end end
#user_mask(target)
# File 'lib/fileutils.rb', line 1642
def user_mask(target) #:nodoc: target.each_char.inject(0) do |mask, chr| case chr when "u" mask | 04700 when "g" mask | 02070 when "o" mask | 01007 when "a" mask | 07777 else raise ArgumentError, "invalid `who' symbol in file mode: #{chr}" end end end