Module: FileUtils
Overview
fileutils.rb
Copyright © 2000-2007 Minero Aoki
This program is free software. You can distribute/modify this program under the same terms of ruby.
module FileUtils
Namespace for several file utility methods for copying, moving, removing, etc.
Module Functions
require 'fileutils'
FileUtils.cd(dir, **)
FileUtils.cd(dir, **) {|dir| block }
FileUtils.pwd()
FileUtils.mkdir(dir, **)
FileUtils.mkdir(list, **)
FileUtils.mkdir_p(dir, **)
FileUtils.mkdir_p(list, **)
FileUtils.rmdir(dir, **)
FileUtils.rmdir(list, **)
FileUtils.ln(target, link, **)
FileUtils.ln(targets, dir, **)
FileUtils.ln_s(target, link, **)
FileUtils.ln_s(targets, dir, **)
FileUtils.ln_sf(target, link, **)
FileUtils.cp(src, dest, **)
FileUtils.cp(list, dir, **)
FileUtils.cp_r(src, dest, **)
FileUtils.cp_r(list, dir, **)
FileUtils.mv(src, dest, **)
FileUtils.mv(list, dir, **)
FileUtils.rm(list, **)
FileUtils.rm_r(list, **)
FileUtils.rm_rf(list, **)
FileUtils.install(src, dest, **)
FileUtils.chmod(mode, list, **)
FileUtils.chmod_R(mode, list, **)
FileUtils.chown(user, group, list, **)
FileUtils.chown_R(user, group, list, **)
FileUtils.touch(list, **)
Possible options
are:
:force
-
forced operation (rewrite files if exist, remove directories if not empty, etc.);
:verbose
-
print command to be run, in bash syntax, before performing it;
:preserve
-
preserve object’s group, user and modification time on copying;
:noop
-
no changes are made (usable in combination with
:verbose
which will print the command to run)
Each method documents the options that it honours. See also ::commands, ::options and ::options_of methods to introspect which command have which options.
All methods that have the concept of a “source” file or directory can take either one file or a list of files in that argument. See the method documentation for examples.
There are some ‘low level’ methods, which do not accept keyword arguments:
FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
FileUtils.copy_file(src, dest, preserve = false, dereference = true)
FileUtils.copy_stream(srcstream, deststream)
FileUtils.remove_entry(path, force = false)
FileUtils.remove_entry_secure(path, force = false)
FileUtils.remove_file(path, force = false)
FileUtils.compare_file(path_a, path_b)
FileUtils.compare_stream(stream_a, stream_b)
FileUtils.uptodate?(file, cmp_list)
module FileUtils::Verbose
This module has all methods of FileUtils module, but it outputs messages before acting. This equates to passing the :verbose
flag to methods in FileUtils.
module FileUtils::NoWrite
This module has all methods of FileUtils module, but never changes files/directories. This equates to passing the :noop
flag to methods in FileUtils.
module FileUtils::DryRun
This module has all methods of FileUtils module, but never changes files/directories. This equates to passing the :noop
and :verbose
flags to methods in FileUtils.
Defined Under Namespace
Modules: DryRun, LowMethods, NoWrite, StreamUtils_, Verbose Classes: Entry_
Constant Summary collapse
- VERSION =
"1.4.1"
Class Method Summary collapse
-
.cd(dir, verbose: nil, &block) ⇒ Object
Changes the current directory to the directory
dir
. -
.chdir ⇒ Object
Changes the current directory to the directory
dir
. -
.chmod(mode, list, noop: nil, verbose: nil) ⇒ Object
Changes permission bits on the named files (in
list
) to the bit pattern represented bymode
. -
.chmod_R(mode, list, noop: nil, verbose: nil, force: nil) ⇒ Object
Changes permission bits on the named files (in
list
) to the bit pattern represented bymode
. -
.chown(user, group, list, noop: nil, verbose: nil) ⇒ Object
Changes owner and group on the named files (in
list
) to the useruser
and the groupgroup
. -
.chown_R(user, group, list, noop: nil, verbose: nil, force: nil) ⇒ Object
Changes owner and group on the named files (in
list
) to the useruser
and the groupgroup
recursively. -
.cmp ⇒ Object
Returns true if the contents of a file
a
and a fileb
are identical. -
.collect_method(opt) ⇒ Object
Returns an Array of methods names which have the option
opt
. -
.commands ⇒ Object
Returns an Array of names of high-level methods that accept any keyword arguments.
-
.compare_file(a, b) ⇒ Object
Returns true if the contents of a file
a
and a fileb
are identical. -
.compare_stream(a, b) ⇒ Object
Returns true if the contents of a stream
a
andb
are identical. -
.copy ⇒ Object
Copies a file content
src
todest
. -
.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) ⇒ Object
Copies a file system entry
src
todest
. -
.copy_file(src, dest, preserve = false, dereference = true) ⇒ Object
Copies file contents of
src
todest
. -
.copy_stream(src, dest) ⇒ Object
Copies stream
src
todest
. -
.cp(src, dest, preserve: nil, noop: nil, verbose: nil) ⇒ Object
Copies a file content
src
todest
. -
.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false) ⇒ Object
Hard link
src
todest
. -
.cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) ⇒ Object
Copies
src
todest
. -
.getwd ⇒ Object
Returns the name of the current directory.
-
.have_option?(mid, opt) ⇒ Boolean
Returns true if the method
mid
have an optionopt
. -
.identical? ⇒ Object
Returns true if the contents of a file
a
and a fileb
are identical. -
.install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) ⇒ Object
If
src
is not same asdest
, copies it and changes the permission mode tomode
. -
.link ⇒ Object
:call-seq: FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil) FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil) FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil).
-
.link_entry(src, dest, dereference_root = false, remove_destination = false) ⇒ Object
Hard links a file system entry
src
todest
. -
.ln(src, dest, force: nil, noop: nil, verbose: nil) ⇒ Object
:call-seq: FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil) FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil) FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil).
-
.ln_s(src, dest, force: nil, noop: nil, verbose: nil) ⇒ Object
:call-seq: FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil) FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil) FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil).
-
.ln_sf(src, dest, noop: nil, verbose: nil) ⇒ Object
:call-seq: FileUtils.ln_sf(*args).
-
.makedirs ⇒ Object
Creates a directory and all its parent directories.
-
.mkdir(list, mode: nil, noop: nil, verbose: nil) ⇒ Object
Creates one or more directories.
-
.mkdir_p(list, mode: nil, noop: nil, verbose: nil) ⇒ Object
Creates a directory and all its parent directories.
-
.mkpath ⇒ Object
Creates a directory and all its parent directories.
-
.move ⇒ Object
Moves file(s)
src
todest
. -
.mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) ⇒ Object
Moves file(s)
src
todest
. -
.options ⇒ Object
Returns an Array of option names.
-
.options_of(mid) ⇒ Object
Returns an Array of option names of the method
mid
. -
.private_module_function(name) ⇒ Object
:nodoc:.
-
.pwd ⇒ Object
Returns the name of the current directory.
-
.remove ⇒ Object
Remove file(s) specified in
list
. -
.remove_dir(path, force = false) ⇒ Object
Removes a directory
dir
and its contents recursively. -
.remove_entry(path, force = false) ⇒ Object
This method removes a file system entry
path
. -
.remove_entry_secure(path, force = false) ⇒ Object
This method removes a file system entry
path
. -
.remove_file(path, force = false) ⇒ Object
Removes a file
path
. -
.rm(list, force: nil, noop: nil, verbose: nil) ⇒ Object
Remove file(s) specified in
list
. -
.rm_f(list, noop: nil, verbose: nil) ⇒ Object
Equivalent to.
-
.rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) ⇒ Object
remove files
list
[0]list
[1]… -
.rm_rf(list, noop: nil, verbose: nil, secure: nil) ⇒ Object
Equivalent to.
-
.rmdir(list, parents: nil, noop: nil, verbose: nil) ⇒ Object
Removes one or more directories.
-
.rmtree ⇒ Object
Equivalent to.
-
.safe_unlink ⇒ Object
Equivalent to.
-
.symlink ⇒ Object
:call-seq: FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil) FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil) FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil).
-
.touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) ⇒ Object
Updates modification time (mtime) and access time (atime) of file(s) in
list
. -
.uptodate?(new, old_list) ⇒ Boolean
Returns true if
new
is newer than allold_list
.
Instance Method Summary collapse
-
#apply_mask(mode, user_mask, op, mode_mask) ⇒ Object
:nodoc:.
-
#fu_get_gid(group) ⇒ Object
:nodoc:.
-
#fu_get_uid(user) ⇒ Object
:nodoc:.
-
#fu_have_symlink? ⇒ Boolean
:nodoc:.
-
#fu_mkdir(path, mode) ⇒ Object
:nodoc:.
-
#fu_mode(mode, path) ⇒ Object
:nodoc:.
-
#fu_stat_identical_entry?(a, b) ⇒ Boolean
:nodoc:.
-
#mode_to_s(mode) ⇒ Object
:nodoc:.
-
#remove_trailing_slash(dir) ⇒ Object
:nodoc:.
-
#symbolic_modes_to_i(mode_sym, path) ⇒ Object
:nodoc:.
-
#user_mask(target) ⇒ Object
:nodoc:.
Class Method Details
.cd(dir, verbose: nil, &block) ⇒ Object
Changes the current directory to the directory dir
.
If this method is called with block, resumes to the previous working directory after the block execution has finished.
FileUtils.cd('/') # change directory
FileUtils.cd('/', verbose: true) # change directory and report it
FileUtils.cd('/') do # change directory
# ... # do something
end # return to original directory
137 138 139 140 141 142 |
# File 'lib/fileutils.rb', line 137 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 ⇒ Object
Changes the current directory to the directory dir
.
If this method is called with block, resumes to the previous working directory after the block execution has finished.
FileUtils.cd('/') # change directory
FileUtils.cd('/', verbose: true) # change directory and report it
FileUtils.cd('/') do # change directory
# ... # do something
end # return to original directory
145 146 147 148 149 150 |
# File 'lib/fileutils.rb', line 145 def cd(dir, verbose: nil, &block) # :yield: dir "cd #{dir}" if verbose result = Dir.chdir(dir, &block) 'cd -' if verbose and block result end |
.chmod(mode, list, noop: nil, verbose: nil) ⇒ Object
Changes permission bits on the named files (in list
) to the bit pattern represented by mode
.
mode
is the symbolic and absolute mode can be used.
Absolute mode is
FileUtils.chmod 0755, 'somecommand'
FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
FileUtils.chmod 0755, '/usr/bin/ruby', verbose: true
Symbolic mode is
FileUtils.chmod "u=wrx,go=rx", 'somecommand'
FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', verbose: true
- “a”
-
is user, group, other mask.
- “u”
-
is user’s mask.
- “g”
-
is group’s mask.
- “o”
-
is other’s mask.
- “w”
-
is write permission.
- “r”
-
is read permission.
- “x”
-
is execute permission.
- “X”
-
is execute permission for directories only, must be used in conjunction with “+”
- “s”
-
is uid, gid.
- “t”
-
is sticky bit.
- “+”
-
is added to a class given the specified mode.
- “-”
-
Is removed from a given class given mode.
- “=”
-
Is the exact nature of the class will be given a specified mode.
1012 1013 1014 1015 1016 1017 1018 1019 |
# File 'lib/fileutils.rb', line 1012 def chmod(mode, list, noop: nil, verbose: nil) list = fu_list(list) sprintf('chmod %s %s', mode_to_s(mode), list.join(' ')) if verbose return if noop list.each do |path| Entry_.new(path).chmod(fu_mode(mode, path)) end end |
.chmod_R(mode, list, noop: nil, verbose: nil, force: nil) ⇒ Object
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 |
# File 'lib/fileutils.rb', line 1029 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) ⇒ Object
Changes owner and group on the named files (in list
) to the user user
and the group group
. user
and group
may be an ID (Integer/String) or a name (String). If user
or group
is nil, this method does not change the attribute.
FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), verbose: true
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 |
# File 'lib/fileutils.rb', line 1057 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) ⇒ Object
Changes owner and group on the named files (in list
) to the user user
and the group group
recursively. user
and group
may be an ID (Integer/String) or a name (String). If user
or group
is nil, this method does not change the attribute.
FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', verbose: true
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 |
# File 'lib/fileutils.rb', line 1081 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 ⇒ Object
Returns true if the contents of a file a
and a file b
are identical.
FileUtils.compare_file('somefile', 'somefile') #=> true
FileUtils.compare_file('/dev/null', '/dev/urandom') #=> false
827 828 829 830 831 832 833 834 |
# File 'lib/fileutils.rb', line 827 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 |
.collect_method(opt) ⇒ Object
Returns an Array of methods names which have the option opt
.
p FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
1679 1680 1681 |
# File 'lib/fileutils.rb', line 1679 def self.collect_method(opt) OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) } end |
.commands ⇒ Object
Returns an Array of names of high-level methods that accept any keyword arguments.
p FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...]
1640 1641 1642 |
# File 'lib/fileutils.rb', line 1640 def self.commands OPT_TABLE.keys end |
.compare_file(a, b) ⇒ Object
816 817 818 819 820 821 822 823 |
# File 'lib/fileutils.rb', line 816 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) ⇒ Object
Returns true if the contents of a stream a
and b
are identical.
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 |
# File 'lib/fileutils.rb', line 834 def compare_stream(a, b) bsize = fu_stream_blksize(a, b) if RUBY_VERSION > "2.4" sa = String.new(capacity: bsize) sb = String.new(capacity: bsize) else sa = String.new sb = String.new end begin a.read(bsize, sa) b.read(bsize, sb) return true if sa.empty? && sb.empty? end while sa == sb false end |
.copy ⇒ Object
Copies a file content src
to dest
. If dest
is a directory, copies src
to dest/src
.
If src
is a list of files, then dest
must be a directory.
FileUtils.cp 'eval.c', 'eval.c.org'
FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true
FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
435 436 437 438 439 440 441 |
# File 'lib/fileutils.rb', line 435 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 |
.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) ⇒ Object
Copies a file system entry src
to dest
. If src
is a directory, this method copies its contents recursively. This method preserves file types, c.f. symlink, directory… (FIFO, device files and etc. are not supported yet)
Both of src
and dest
must be a path name. src
must exist, dest
must not exist.
If preserve
is true, this method preserves owner, group, and modified time. Permissions are copied regardless preserve
.
If dereference_root
is true, this method dereference tree root.
If remove_destination
is true, this method removes each destination file before copy.
489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
# File 'lib/fileutils.rb', line 489 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) ⇒ Object
Copies file contents of src
to dest
. Both of src
and dest
must be a path name.
509 510 511 512 513 |
# File 'lib/fileutils.rb', line 509 def copy_file(src, dest, preserve = false, dereference = true) ent = Entry_.new(src, nil, dereference) ent.copy_file dest ent. dest if preserve end |
.copy_stream(src, dest) ⇒ Object
Copies stream src
to dest
. src
must respond to #read(n) and dest
must respond to #write(str).
521 522 523 |
# File 'lib/fileutils.rb', line 521 def copy_stream(src, dest) IO.copy_stream(src, dest) end |
.cp(src, dest, preserve: nil, noop: nil, verbose: nil) ⇒ Object
Copies a file content src
to dest
. If dest
is a directory, copies src
to dest/src
.
If src
is a list of files, then dest
must be a directory.
FileUtils.cp 'eval.c', 'eval.c.org'
FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true
FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
426 427 428 429 430 431 432 |
# File 'lib/fileutils.rb', line 426 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) ⇒ Object
Hard link src
to dest
. If src
is a directory, this method links all its contents recursively. If dest
is a directory, links src
to dest/src
.
src
can be a list of files.
If dereference_root
is true, this method dereference tree root.
If remove_destination
is true, this method removes each destination file before copy.
FileUtils.rm_r site_ruby + '/mylib', force: true
FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
# Examples of linking several files to target directory.
FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', noop: true, verbose: true
# If you want to link all contents of a directory instead of the
# directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
# use the following code.
FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
339 340 341 342 343 344 345 346 |
# File 'lib/fileutils.rb', line 339 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) ⇒ Object
Copies src
to dest
. If src
is a directory, this method copies all its contents recursively. If dest
is a directory, copies src
to dest/src
.
src
can be a list of files.
If dereference_root
is true, this method dereference tree root.
If remove_destination
is true, this method removes each destination file before copy.
# Installing Ruby library "mylib" under the site_ruby
FileUtils.rm_r site_ruby + '/mylib', force: true
FileUtils.cp_r 'lib/', site_ruby + '/mylib'
# Examples of copying several files to target directory.
FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', noop: true, verbose: true
# If you want to copy all contents of a directory instead of the
# directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
# use following code.
FileUtils.cp_r 'src/.', 'dest' # cp_r('src', 'dest') makes dest/src,
# but this doesn't.
463 464 465 466 467 468 469 470 |
# File 'lib/fileutils.rb', line 463 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 ⇒ Object
Returns the name of the current directory.
120 121 122 |
# File 'lib/fileutils.rb', line 120 def pwd Dir.pwd end |
.have_option?(mid, opt) ⇒ Boolean
1660 1661 1662 1663 |
# File 'lib/fileutils.rb', line 1660 def self.have_option?(mid, opt) li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}" li.include?(opt) end |
.identical? ⇒ Object
Returns true if the contents of a file a
and a file b
are identical.
FileUtils.compare_file('somefile', 'somefile') #=> true
FileUtils.compare_file('/dev/null', '/dev/urandom') #=> false
826 827 828 829 830 831 832 833 |
# File 'lib/fileutils.rb', line 826 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 |
.install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) ⇒ Object
If src
is not same as dest
, copies it and changes the permission mode to mode
. If dest
is a directory, destination is dest
/src
. This method removes destination before copy.
FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true
FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 |
# File 'lib/fileutils.rb', line 862 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 copy_file s, d 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 ⇒ Object
:call-seq:
FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil)
FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil)
FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil)
In the first form, creates a hard link link
which points to target
. If link
already exists, raises Errno::EEXIST. But if the force
option is set, overwrites link
.
FileUtils.ln 'gcc', 'cc', verbose: true
FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
In the second form, creates a link dir/target
pointing to target
. In the third form, creates several hard links in the directory dir
, pointing to each item in targets
. If dir
is not a directory, raises Errno::ENOTDIR.
FileUtils.cd '/sbin'
FileUtils.ln %w(cp mv mkdir), '/bin' # Now /sbin/cp and /bin/cp are linked.
313 314 315 316 317 318 319 320 |
# File 'lib/fileutils.rb', line 313 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 |
.link_entry(src, dest, dereference_root = false, remove_destination = false) ⇒ Object
Hard links a file system entry src
to dest
. If src
is a directory, this method links its contents recursively.
Both of src
and dest
must be a path name. src
must exist, dest
must not exist.
If dereference_root
is true, this method dereferences the tree root.
If remove_destination
is true, this method removes each destination file before copy.
406 407 408 409 410 411 412 |
# File 'lib/fileutils.rb', line 406 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) ⇒ Object
:call-seq:
FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil)
FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil)
FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil)
In the first form, creates a hard link link
which points to target
. If link
already exists, raises Errno::EEXIST. But if the force
option is set, overwrites link
.
FileUtils.ln 'gcc', 'cc', verbose: true
FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
In the second form, creates a link dir/target
pointing to target
. In the third form, creates several hard links in the directory dir
, pointing to each item in targets
. If dir
is not a directory, raises Errno::ENOTDIR.
FileUtils.cd '/sbin'
FileUtils.ln %w(cp mv mkdir), '/bin' # Now /sbin/cp and /bin/cp are linked.
303 304 305 306 307 308 309 310 |
# File 'lib/fileutils.rb', line 303 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, noop: nil, verbose: nil) ⇒ Object
:call-seq:
FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil)
In the first form, creates a symbolic link link
which points to target
. If link
already exists, raises Errno::EEXIST. But if the force
option is set, overwrites link
.
FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
In the second form, creates a link dir/target
pointing to target
. In the third form, creates several symbolic links in the directory dir
, pointing to each item in targets
. If dir
is not a directory, raises Errno::ENOTDIR.
FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin'
369 370 371 372 373 374 375 376 |
# File 'lib/fileutils.rb', line 369 def ln_s(src, dest, force: nil, noop: nil, verbose: nil) "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) ⇒ Object
390 391 392 |
# File 'lib/fileutils.rb', line 390 def ln_sf(src, dest, noop: nil, verbose: nil) ln_s src, dest, force: true, noop: noop, verbose: verbose end |
.makedirs ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/fileutils.rb', line 240 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.map {|path| remove_trailing_slash(path)}.each do |path| # optimize for the most common case begin fu_mkdir path, mode next rescue SystemCallError next if File.directory?(path) end stack = [] until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/" stack.push path path = File.dirname(path) end stack.pop # root directory should exist stack.reverse_each do |dir| begin fu_mkdir dir, mode rescue SystemCallError raise unless File.directory?(dir) end end end return *list end |
.mkdir(list, mode: nil, noop: nil, verbose: nil) ⇒ Object
180 181 182 183 184 185 186 187 188 |
# File 'lib/fileutils.rb', line 180 def mkdir(list, mode: nil, noop: nil, verbose: nil) list = fu_list(list) "mkdir #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose return if noop list.each do |dir| fu_mkdir dir, mode end end |
.mkdir_p(list, mode: nil, noop: nil, verbose: nil) ⇒ Object
Creates a directory and all its parent directories. For example,
FileUtils.mkdir_p '/usr/local/lib/ruby'
causes to make following directories, if they do not exist.
-
/usr
-
/usr/local
-
/usr/local/lib
-
/usr/local/lib/ruby
You can pass several directories at a time in a list.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/fileutils.rb', line 206 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.map {|path| remove_trailing_slash(path)}.each do |path| # optimize for the most common case begin fu_mkdir path, mode next rescue SystemCallError next if File.directory?(path) end stack = [] until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/" stack.push path path = File.dirname(path) end stack.pop # root directory should exist stack.reverse_each do |dir| begin fu_mkdir dir, mode rescue SystemCallError raise unless File.directory?(dir) end end end return *list end |
.mkpath ⇒ Object
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/fileutils.rb', line 239 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.map {|path| remove_trailing_slash(path)}.each do |path| # optimize for the most common case begin fu_mkdir path, mode next rescue SystemCallError next if File.directory?(path) end stack = [] until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/" stack.push path path = File.dirname(path) end stack.pop # root directory should exist stack.reverse_each do |dir| begin fu_mkdir dir, mode rescue SystemCallError raise unless File.directory?(dir) end end end return *list end |
.move ⇒ Object
Moves file(s) src
to dest
. If file
and dest
exist on the different disk partition, the file is copied then the original file is removed.
FileUtils.mv 'badname.rb', 'goodname.rb'
FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error
FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
# File 'lib/fileutils.rb', line 565 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 |
.mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) ⇒ Object
Moves file(s) src
to dest
. If file
and dest
exist on the different disk partition, the file is copied then the original file is removed.
FileUtils.mv 'badname.rb', 'goodname.rb'
FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error
FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
# File 'lib/fileutils.rb', line 536 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 ⇒ Object
Returns an Array of option names.
p FileUtils. #=> ["noop", "force", "verbose", "preserve", "mode"]
1649 1650 1651 |
# File 'lib/fileutils.rb', line 1649 def self. OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s } end |
.options_of(mid) ⇒ Object
Returns an Array of option names of the method mid
.
p FileUtils.(:rm) #=> ["noop", "verbose", "force"]
1670 1671 1672 |
# File 'lib/fileutils.rb', line 1670 def self.(mid) OPT_TABLE[mid.to_s].map {|sym| sym.to_s } end |
.private_module_function(name) ⇒ Object
:nodoc:
107 108 109 110 |
# File 'lib/fileutils.rb', line 107 def self.private_module_function(name) #:nodoc: module_function name private_class_method name end |
.pwd ⇒ Object
Returns the name of the current directory.
115 116 117 |
# File 'lib/fileutils.rb', line 115 def pwd Dir.pwd end |
.remove ⇒ Object
587 588 589 590 591 592 593 594 595 |
# File 'lib/fileutils.rb', line 587 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 |
.remove_dir(path, force = false) ⇒ Object
Removes a directory dir
and its contents recursively. This method ignores StandardError if force
is true.
805 806 807 |
# File 'lib/fileutils.rb', line 805 def remove_dir(path, force = false) remove_entry path, force # FIXME?? check if it is a directory end |
.remove_entry(path, force = false) ⇒ Object
This method removes a file system entry path
. path
might be a regular file, a directory, or something. If path
is a directory, remove it recursively.
See also remove_entry_secure.
777 778 779 780 781 782 783 784 785 786 787 |
# File 'lib/fileutils.rb', line 777 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) ⇒ Object
This method removes a file system entry path
. path
shall be a regular file, a directory, or something. If path
is a directory, remove it recursively. This method is required to avoid TOCTTOU (time-of-check-to-time-of-use) local security vulnerability of rm_r. #rm_r causes security hole when:
-
Parent directory is world writable (including /tmp).
-
Removing directory tree includes world writable directory.
-
The system has symbolic link.
To avoid this security hole, this method applies special preprocess. If path
is a directory, this method chown(2) and chmod(2) all removing directories. This requires the current process is the owner of the removing whole directory tree, or is 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 set.
WARNING: Only the owner of the removing directory tree, or Unix super user (root) should invoke this method. Otherwise this method does not work.
For details of this security vulnerability, see Perl’s case:
For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 |
# File 'lib/fileutils.rb', line 684 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) ⇒ Object
Removes a file path
. This method ignores StandardError if force
is true.
794 795 796 797 798 |
# File 'lib/fileutils.rb', line 794 def remove_file(path, force = false) Entry_.new(path).remove_file rescue raise unless force end |
.rm(list, force: nil, noop: nil, verbose: nil) ⇒ Object
576 577 578 579 580 581 582 583 584 |
# File 'lib/fileutils.rb', line 576 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) ⇒ Object
595 596 597 |
# File 'lib/fileutils.rb', line 595 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) ⇒ Object
remove files list
[0] list
[1]… If list
[n] is a directory, removes its all contents recursively. This method ignores StandardError when :force option is set.
FileUtils.rm_r Dir.glob('/tmp/*')
FileUtils.rm_r 'some_dir', force: true
WARNING: This method causes local vulnerability if one of parent directories or removing directory tree are world writable (including /tmp, whose permission is 1777), and the current process has strong privilege such as Unix super user (root), and the system has symbolic link. For secure removing, read the documentation of remove_entry_secure carefully, and set :secure option to true. Default is secure: false
.
NOTE: This method calls remove_entry_secure if :secure option is set. See also remove_entry_secure.
622 623 624 625 626 627 628 629 630 631 632 633 |
# File 'lib/fileutils.rb', line 622 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) ⇒ Object
644 645 646 |
# File 'lib/fileutils.rb', line 644 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) ⇒ Object
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/fileutils.rb', line 263 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 ⇒ Object
649 650 651 |
# File 'lib/fileutils.rb', line 649 def rm_rf(list, noop: nil, verbose: nil, secure: nil) rm_r list, force: true, noop: noop, verbose: verbose, secure: secure end |
.safe_unlink ⇒ Object
600 601 602 |
# File 'lib/fileutils.rb', line 600 def rm_f(list, noop: nil, verbose: nil) rm list, force: true, noop: noop, verbose: verbose end |
.symlink ⇒ Object
:call-seq:
FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil)
In the first form, creates a symbolic link link
which points to target
. If link
already exists, raises Errno::EEXIST. But if the force
option is set, overwrites link
.
FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
In the second form, creates a link dir/target
pointing to target
. In the third form, creates several symbolic links in the directory dir
, pointing to each item in targets
. If dir
is not a directory, raises Errno::ENOTDIR.
FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin'
379 380 381 382 383 384 385 386 |
# File 'lib/fileutils.rb', line 379 def ln_s(src, dest, force: nil, noop: nil, verbose: nil) "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 |
.touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) ⇒ Object
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 |
# File 'lib/fileutils.rb', line 1137 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
Returns true if new
is newer than all old_list
. Non-existent files are older than any file.
FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \
system 'make hello.o'
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/fileutils.rb', line 155 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 Method Details
#apply_mask(mode, user_mask, op, mode_mask) ⇒ Object
:nodoc:
907 908 909 910 911 912 913 914 915 916 |
# File 'lib/fileutils.rb', line 907 def apply_mask(mode, user_mask, op, mode_mask) #:nodoc: case op when '=' (mode & ~user_mask) | (user_mask & mode_mask) when '+' mode | (user_mask & mode_mask) when '-' mode & ~(user_mask & mode_mask) end end |
#fu_get_gid(group) ⇒ Object
:nodoc:
1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 |
# File 'lib/fileutils.rb', line 1116 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) ⇒ Object
:nodoc:
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 |
# File 'lib/fileutils.rb', line 1102 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_have_symlink? ⇒ Boolean
:nodoc:
756 757 758 759 760 761 762 |
# File 'lib/fileutils.rb', line 756 def fu_have_symlink? #:nodoc: File.symlink nil, nil rescue NotImplementedError return false rescue TypeError return true end |
#fu_mkdir(path, mode) ⇒ Object
:nodoc:
244 245 246 247 248 249 250 251 252 |
# File 'lib/fileutils.rb', line 244 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) ⇒ Object
:nodoc:
971 972 973 |
# File 'lib/fileutils.rb', line 971 def fu_mode(mode, path) #:nodoc: mode.is_a?(String) ? symbolic_modes_to_i(mode, path) : mode end |
#fu_stat_identical_entry?(a, b) ⇒ Boolean
:nodoc:
765 766 767 |
# File 'lib/fileutils.rb', line 765 def fu_stat_identical_entry?(a, b) #:nodoc: a.dev == b.dev and a.ino == b.ino end |
#mode_to_s(mode) ⇒ Object
:nodoc:
976 977 978 |
# File 'lib/fileutils.rb', line 976 def mode_to_s(mode) #:nodoc: mode.is_a?(String) ? mode : "%o" % mode end |
#remove_trailing_slash(dir) ⇒ Object
:nodoc:
167 168 169 |
# File 'lib/fileutils.rb', line 167 def remove_trailing_slash(dir) #:nodoc: dir == '/' ? dir : dir.chomp(?/) end |
#symbolic_modes_to_i(mode_sym, path) ⇒ Object
:nodoc:
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 |
# File 'lib/fileutils.rb', line 919 def symbolic_modes_to_i(mode_sym, path) #:nodoc: mode = if File::Stat === path path.mode else File.stat(path).mode end 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 FileTest.directory? path 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) ⇒ Object
:nodoc:
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 |
# File 'lib/fileutils.rb', line 889 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 |