Spec-Zone.ru › Ruby 2.2

модуль FileUtils

Включенные модули:
FileUtils::StreamUtils_

fileutils.rb

Авторские права © 2000-2007 Minero Aoki

Данная программа является свободной программой. Вы можете распространять/изменять эту программу на тех же условиях, что и рубин.

модуль FileUtils

Пространство имен для нескольких методов работы с файлами для копирования, перемещения, удаления и т.д.

Модуль Функции

require 'fileutils'

FileUtils.cd(dir, options)
FileUtils.cd(dir, options) {|dir| .... }
FileUtils.pwd()
FileUtils.mkdir(dir, options)
FileUtils.mkdir(list, options)
FileUtils.mkdir_p(dir, options)
FileUtils.mkdir_p(list, options)
FileUtils.rmdir(dir, options)
FileUtils.rmdir(list, options)
FileUtils.ln(old, new, options)
FileUtils.ln(list, destdir, options)
FileUtils.ln_s(old, new, options)
FileUtils.ln_s(list, destdir, options)
FileUtils.ln_sf(src, dest, options)
FileUtils.cp(src, dest, options)
FileUtils.cp(list, dir, options)
FileUtils.cp_r(src, dest, options)
FileUtils.cp_r(list, dir, options)
FileUtils.mv(src, dest, options)
FileUtils.mv(list, dir, options)
FileUtils.rm(list, options)
FileUtils.rm_r(list, options)
FileUtils.rm_rf(list, options)
FileUtils.install(src, dest, mode = <src's>, options)
FileUtils.chmod(mode, list, options)
FileUtils.chmod_R(mode, list, options)
FileUtils.chown(user, group, list, options)
FileUtils.chown_R(user, group, list, options)
FileUtils.touch(list, options)

Параметр options — это хеш опций, взятый из списка :force, :noop, :preserve, и :verbose. :noop означает, что никаких изменений не производится. Два других параметра очевидны. Каждый метод документирует опции, которые он поддерживает.

Все методы, которые имеют понятие «исходного» файла или каталога, могут принимать либо один файл, либо список файлов в этом аргументе. Примеры смотрите в документации к методу.

Есть некоторые методы «низкого уровня», которые не принимают никаких опций:

FileUtils.copy_entry(src, dest, preserve = false, dereference = 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)

модуль FileUtils::Verbose

Этот модуль содержит все методы модуля FileUtils, но выводит сообщения перед выполнением действий. Это эквивалентно передаче флага :verbose методам в модуле FileUtils.

модуль FileUtils::NoWrite

Этот модуль содержит все методы модуля FileUtils, но никогда не изменяет файлы/каталоги. Это эквивалентно передаче флага :noop методам в модуле FileUtils.

модуль FileUtils::DryRun

Этот модуль содержит все методы модуля FileUtils, но никогда не изменяет файлы/каталоги. Это эквивалентно передаче флагов :noop и :verbose методам в модуле FileUtils.

Константы

LN_SUPPORTED
LOW_METHODS
METHODS
RUBY

Путь к текущей выполняемой программе Ruby

Публичные методы класса

cd(dir, options = {}) { |dir| ... } Показать исходный код
# File lib/fileutils.rb, line 124
def cd(dir, options = {}, &block) # :yield: dir
  fu_check_options options, OPT_TABLE['cd']
  fu_output_message "cd #{dir}" if options[:verbose]
  Dir.chdir(dir, &block)
  fu_output_message 'cd -' if options[:verbose] and block
end

Опции: verbose

Изменяет текущий каталог на каталог dir.

Если этот метод вызывается с блоком, возвращается к старому рабочему каталогу после завершения выполнения блока.

FileUtils.cd('/', :verbose => true)   # chdir and report it

FileUtils.cd('/') do  # chdir
  [...]               # do something
end                   # return to original directory
Также известен как: chdir
chdir(dir, options = {})
Псевдоним для: cd
chmod(mode, list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 994
def chmod(mode, list, options = {})
  fu_check_options options, OPT_TABLE['chmod']
  list = fu_list(list)
  fu_output_message sprintf('chmod %s %s', mode_to_s(mode), list.join(' ')) if options[:verbose]
  return if options[:noop]
  list.each do |path|
    Entry_.new(path).chmod(fu_mode(mode, path))
  end
end

Опции: noop verbose

Изменяет биты разрешений для указанных файлов (в list) на битовую модель, представленную mode.

mode может быть символьный и абсолютный режим.

Абсолютный режим это

FileUtils.chmod 0755, 'somecommand'
FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true

Символьный режим это

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”

это маска пользователя, группы и других.

“u”

это маска пользователя.

“g”

это маска группы.

“o”

это маска других.

“w”

это разрешение на запись.

“r”

это разрешение на чтение.

“x”

это разрешение на выполнение.

“X”

это разрешение на выполнение только для каталогов, должно использоваться вместе с “+”

“s”

это uid, gid.

“t”

это бит «липкости».

“+”

добавляется к классу с указанным режимом.

“-”

удаляется из данного класса с указанным режимом.

“=”

точно определяет характер класса с указанным режимом.

chmod_R(mode, list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 1016
def chmod_R(mode, list, options = {})
  fu_check_options options, OPT_TABLE['chmod_R']
  list = fu_list(list)
  fu_output_message sprintf('chmod -R%s %s %s',
                            (options[:force] ? 'f' : ''),
                            mode_to_s(mode), list.join(' ')) if options[:verbose]
  return if options[:noop]
  list.each do |root|
    Entry_.new(root).traverse do |ent|
      begin
        ent.chmod(fu_mode(mode, ent.path))
      rescue
        raise unless options[:force]
      end
    end
  end
end

Опции: noop verbose force

Изменяет биты разрешений для указанных файлов (в list) на битовую модель, представленную mode.

FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
chown(user, group, list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 1049
def chown(user, group, list, options = {})
  fu_check_options options, OPT_TABLE['chown']
  list = fu_list(list)
  fu_output_message sprintf('chown %s %s',
                            (group ? "#{user}:#{group}" : user || ':'),
                            list.join(' ')) if options[:verbose]
  return if options[:noop]
  uid = fu_get_uid(user)
  gid = fu_get_gid(group)
  list.each do |path|
    Entry_.new(path).chown uid, gid
  end
end

Опции: noop verbose

Изменяет владельца и группу для указанных файлов (в list) на пользователя user и группу group. user и group могут быть ID (целое число/строка) или именем (строка). Если user или group равно nil, этот метод не изменяет атрибут.

FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true
chown_R(user, group, list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 1078
def chown_R(user, group, list, options = {})
  fu_check_options options, OPT_TABLE['chown_R']
  list = fu_list(list)
  fu_output_message sprintf('chown -R%s %s %s',
                            (options[:force] ? 'f' : ''),
                            (group ? "#{user}:#{group}" : user || ':'),
                            list.join(' ')) if options[:verbose]
  return if options[: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 options[:force]
      end
    end
  end
end

Опции: noop verbose force

Рекурсивно изменяет владельца и группу для указанных файлов (в list) на пользователя user и группу group. user и group могут быть ID (целое число/строка) или именем (строка). Если user или group равно nil, этот метод не изменяет атрибут.

FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true
cmp(a, b)
Псевдоним для: compare_file
compare_file(a, b) Показать исходный код
# File lib/fileutils.rb, line 815
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

Возвращает true, если содержимое файла A и файла B идентично.

FileUtils.compare_file('somefile', 'somefile')  #=> true
FileUtils.compare_file('/bin/cp', '/bin/mv')    #=> maybe false
Также известен как: identical?, cmp
compare_stream(a, b) Показать исходный код
# File lib/fileutils.rb, line 833
def compare_stream(a, b)
  bsize = fu_stream_blksize(a, b)
  sa = ""
  sb = ""
  begin
    a.read(bsize, sa)
    b.read(bsize, sb)
    return true if sa.empty? && sb.empty?
  end while sa == sb
  false
end

Возвращает true, если содержимое потока a и b идентично.

copy(src, dest, options = {})
Псевдоним для: cp
copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) Показать исходный код
# File lib/fileutils.rb, line 468
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
  Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    File.unlink destent.path if remove_destination && File.file?(destent.path)
    ent.copy destent.path
  end, proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    ent.copy_metadata destent.path if preserve
  end)
end

Копирует запись файловой системы src в dest. Если src является каталогом, этот метод рекурсивно копирует его содержимое. Этот метод сохраняет типы файлов, например, символическую ссылку, каталог… (файлы FIFO, устройства и т.д. пока не поддерживаются)

И src, и dest должны быть именами путей. src должен существовать, dest не должен существовать.

Если preserve равно true, этот метод сохраняет владельца, группу и время последнего изменения. Разрешения копируются независимо от preserve.

Если dereference_root равно true, этот метод разыменовывает корень дерева.

Если remove_destination равно true, этот метод удаляет каждый целевой файл перед копированием.

copy_file(src, dest, preserve = false, dereference = true) Показать исходный код
# File lib/fileutils.rb, line 484
def copy_file(src, dest, preserve = false, dereference = true)
  ent = Entry_.new(src, nil, dereference)
  ent.copy_file dest
  ent.copy_metadata dest if preserve
end

Копирует содержимое файла src в dest. И src, и dest должны быть именами путей.

copy_stream(src, dest) Показать исходный код
# File lib/fileutils.rb, line 496
def copy_stream(src, dest)
  IO.copy_stream(src, dest)
end

Копирует поток src в dest. src должен отвечать на read(n), а dest должен отвечать на write(str).

cp(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 398
def cp(src, dest, options = {})
  fu_check_options options, OPT_TABLE['cp']
  fu_output_message "cp#{options[:preserve] ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest(src, dest) do |s, d|
    copy_file s, d, options[:preserve]
  end
end

Опции: preserve noop verbose

Копирует содержимое файла src в dest. Если dest является каталогом, копирует src в dest/src.

Если src это список файлов, то dest должен быть каталогом.

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
Также известен как: copy
cp_r(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 437
def cp_r(src, dest, options = {})
  fu_check_options options, OPT_TABLE['cp_r']
  fu_output_message "cp -r#{options[:preserve] ? 'p' : ''}#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  options = options.dup
  options[:dereference_root] = true unless options.key?(:dereference_root)
  fu_each_src_dest(src, dest) do |s, d|
    copy_entry s, d, options[:preserve], options[:dereference_root], options[:remove_destination]
  end
end

Опции: preserve noop verbose dereference_root remove_destination

Копирует src в dest. Если src является каталогом, этот метод рекурсивно копирует все его содержимое. Если dest является каталогом, копирует src в dest/src.

src может быть списком файлов.

# Installing Ruby library "mylib" under the site_ruby
FileUtils.rm_r site_ruby + '/mylib', :force
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/aamine/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.
getwd()
Псевдоним для: pwd
identical?(a, b)
Псевдоним для: compare_file
install(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 856
def install(src, dest, options = {})
  fu_check_options options, OPT_TABLE['install']
  fu_output_message "install -c#{options[:preserve] && ' -p'}#{options[:mode] ? (' -m 0%o' % options[:mode]) : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  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 options[:preserve]
      File.chmod options[:mode], d if options[:mode]
    end
  end
end

Опции: mode preserve noop verbose

Если src не совпадает с dest, копирует его и изменяет режим разрешений на mode. Если dest является каталогом, целевым является dest/src. Этот метод удаляет целевой файл перед копированием.

FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
link(src, dest, options = {})
Псевдоним для: ln
ln(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 313
def ln(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln']
  fu_output_message "ln#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest0(src, dest) do |s,d|
    remove_file d, true if options[:force]
    File.link s, d
  end
end

Параметры: force noop verbose

ln(old, new, options = {})

Создаёт жёсткую ссылку new которая указывает на old. Если new уже существует и это каталог, создаёт ссылку new/old. Если new уже существует и это не каталог, генерирует исключение Errno::EEXIST. Но если установлен параметр :force, перезаписывает new.

FileUtils.ln 'gcc', 'cc', :verbose => true
FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'

ln(list, destdir, options = {})

Создаёт несколько жёстких ссылок в каталоге, каждая из которых указывает на элемент в list. Если destdir не является каталогом, генерируется исключение Errno::ENOTDIR.

include FileUtils
cd '/sbin'
FileUtils.ln %w(cp mv mkdir), '/bin'   # Now /sbin/cp and /bin/cp are linked.
Также используется как: link
ln_s(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 352
def ln_s(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln_s']
  fu_output_message "ln -s#{options[:force] ? 'f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest0(src, dest) do |s,d|
    remove_file d, true if options[:force]
    File.symlink s, d
  end
end

Параметры: force noop verbose

ln_s(old, new, options = {})

Создаёт символическую ссылку new которая указывает на old. Если new уже существует и это каталог, создаёт символическую ссылку new/old. Если new уже существует и это не каталог, генерируется исключение Errno::EEXIST. Но если установлен параметр :force, перезаписывает new.

FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
FileUtils.ln_s 'verylongsourcefilename.c', 'c', :force => true

ln_s(list, destdir, options = {})

Создаёт несколько символических ссылок в каталоге, каждая из которых указывает на элемент в list. Если destdir не является каталогом, генерируется исключение Errno::ENOTDIR.

Если destdir не является каталогом, генерируется исключение Errno::ENOTDIR.

FileUtils.ln_s Dir.glob('bin/*.rb'), '/home/aamine/bin'
Также используется как: symlink
ln_sf(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 375
def ln_sf(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln_sf']
  options = options.dup
  options[:force] = true
  ln_s src, dest, options
end

Параметры: noop verbose

То же, что и

#ln_s(src, dest, :force => true)
makedirs(list, options = {})
Псевдоним для: mkdir_p
mkdir(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 174
def mkdir(list, options = {})
  fu_check_options options, OPT_TABLE['mkdir']
  list = fu_list(list)
  fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
  return if options[:noop]

  list.each do |dir|
    fu_mkdir dir, options[:mode]
  end
end

Параметры: mode noop verbose

Создаёт один или несколько каталогов.

FileUtils.mkdir 'test'
FileUtils.mkdir %w( tmp data )
FileUtils.mkdir 'notexist', :noop => true  # Does not really create.
FileUtils.mkdir 'tmp', :mode => 0700
mkdir_p(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 204
def mkdir_p(list, options = {})
  fu_check_options options, OPT_TABLE['mkdir_p']
  list = fu_list(list)
  fu_output_message "mkdir -p #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
  return *list if options[:noop]

  list.map {|path| remove_tailing_slash(path)}.each do |path|
    # optimize for the most common case
    begin
      fu_mkdir path, options[: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, options[:mode]
      rescue SystemCallError
        raise unless File.directory?(dir)
      end
    end
  end

  return *list
end

Параметры: mode noop verbose

Создаёт каталог и все его родительские каталоги. Например,

FileUtils.mkdir_p '/usr/local/lib/ruby'

приводит к созданию следующих каталогов, если они не существуют.

* /usr
* /usr/local
* /usr/local/lib
* /usr/local/lib/ruby

Вы можете передать несколько каталогов одновременно в списке.

Также используется как: mkpath, makedirs
mkpath(list, options = {})
Псевдоним для: mkdir_p
move(src, dest, options = {})
Псевдоним для: mv
mv(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 513
def mv(src, dest, options = {})
  fu_check_options options, OPT_TABLE['mv']
  fu_output_message "mv#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[: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
        else
          destent.remove_file if rename_cannot_overwrite_file?
        end
      end
      begin
        File.rename s, d
      rescue Errno::EXDEV
        copy_entry s, d, true
        if options[:secure]
          remove_entry_secure s, options[:force]
        else
          remove_entry s, options[:force]
        end
      end
    rescue SystemCallError
      raise unless options[:force]
    end
  end
end

Параметры: force noop verbose

Перемещает файл(ы) src в dest. Если file и dest находятся на разных разделах диска, файл копируется, а затем удаляется исходный файл.

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/aamine/.trash/'
FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
Также используется как: move
pwd() Показать исходный код
# File lib/fileutils.rb, line 102
def pwd
  Dir.pwd
end

Параметры: (нет)

Возвращает имя текущего каталога.

Также используется как: getwd
remove(list, options = {})
Псевдоним для: rm
remove_dir(path, force = false) Показать исходный код
# File lib/fileutils.rb, line 804
def remove_dir(path, force = false)
  remove_entry path, force   # FIXME?? check if it is a directory
end

Удаляет каталог dir и его содержимое рекурсивно. Этот метод игнорирует StandardError, если force равно true.

remove_entry(path, force = false) Показать исходный код
# File lib/fileutils.rb, line 776
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

Этот метод удаляет элемент файловой системы path. path может быть обычным файлом, каталогом или чем-то ещё. Если path является каталогом, удаляет его рекурсивно.

См. также remove_entry_secure.

remove_entry_secure(path, force = false) Показать исходный код
# File lib/fileutils.rb, line 699
def remove_entry_secure(path, force = false)
  unless fu_have_symlink?
    remove_entry path, force
    return
  end
  fullpath = File.expand_path(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
  File.open(fullpath + '/.') {|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
    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

Этот метод удаляет элемент файловой системы path. path должен быть обычным файлом, каталогом или чем-то другим. Если path является каталогом, удаляет его рекурсивно. Этот метод необходим для предотвращения локальной уязвимости безопасности TOCTTOU (время проверки — время использования) метода rm_r. rm_r создаёт уязвимость, когда:

* Parent directory is world writable (including /tmp).
* Removing directory tree includes world writable directory.
* The system has symbolic link.

Чтобы избежать этой уязвимости, этот метод применяет специальную предподготовку. Если path является каталогом, этот метод использует chown(2) и chmod(2) для всех удаляемых каталогов. Это требует, чтобы текущий процесс был владельцем удаляемой цепочки каталогов или имел права суперпользователя (root).

ПРЕДУПРЕЖДЕНИЕ: Вы должны убедиться, что ВСЕ родительские каталоги не могут быть перемещены другими неуправляемыми пользователями. Например, родительские каталоги не должны принадлежать неуправляемым пользователям и не должны быть доступны для записи всем, кроме случаев установки бита "sticky".

ПРЕДУПРЕЖДЕНИЕ: Только владелец удаляемой цепочки каталогов или системный пользователь Unix (root) должны вызывать этот метод. В противном случае этот метод не сработает.

Для подробностей об этой уязвимости безопасности см. пример в Perl:

http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452

Для fileutils.rb эта уязвимость описана в [ruby-dev:26100].

remove_file(path, force = false) Показать исходный код
# File lib/fileutils.rb, line 793
def remove_file(path, force = false)
  Entry_.new(path).remove_file
rescue
  raise unless force
end

Удаляет файл path. Этот метод игнорирует StandardError, если force равно true.

rm(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 565
def rm(list, options = {})
  fu_check_options options, OPT_TABLE['rm']
  list = fu_list(list)
  fu_output_message "rm#{options[:force] ? ' -f' : ''} #{list.join ' '}" if options[:verbose]
  return if options[:noop]

  list.each do |path|
    remove_file path, options[:force]
  end
end

Параметры: force noop verbose

Удаляет файлы, указанные в list. Этот метод не может удалять каталоги. Все StandardError игнорируются, когда установлен параметр :force.

FileUtils.rm %w( junk.txt dust.txt )
FileUtils.rm Dir.glob('*.so')
FileUtils.rm 'NotExistFile', :force => true   # never raises exception
Также используется как: remove
rm_f(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 590
def rm_f(list, options = {})
  fu_check_options options, OPT_TABLE['rm_f']
  options = options.dup
  options[:force] = true
  rm list, options
end

Параметры: noop verbose

Эквивалентно

#rm(list, :force => true)
Также используется как: safe_unlink
rm_r(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 625
def rm_r(list, options = {})
  fu_check_options options, OPT_TABLE['rm_r']
  # options[:secure] = true unless options.key?(:secure)
  list = fu_list(list)
  fu_output_message "rm -r#{options[:force] ? 'f' : ''} #{list.join ' '}" if options[:verbose]
  return if options[:noop]
  list.each do |path|
    if options[:secure]
      remove_entry_secure path, options[:force]
    else
      remove_entry path, options[:force]
    end
  end
end

Параметры: force noop verbose secure

удаляет файлы list[0] list[1]… Если list[n] является каталогом, удаляет все его содержимое рекурсивно. Этот метод игнорирует StandardError, когда установлен параметр :force.

FileUtils.rm_r Dir.glob('/tmp/*')
FileUtils.rm_r '/', :force => true          #  :-)

ПРЕДУПРЕЖДЕНИЕ: Этот метод может привести к локальной уязвимости, если один из родительских каталогов или удаляемая структура каталогов имеют права доступа «для всех» (включая /tmp, права которого составляют 1777), а текущий процесс обладает сильными привилегиями, такими как права суперпользователя Unix (root), а в системе присутствуют символические ссылки. Для безопасного удаления внимательно ознакомьтесь с документацией remove_entry_secure и установите параметр :secure в значение true. По умолчанию :secure=>false.

ПРИМЕЧАНИЕ: Этот метод вызывает remove_entry_secure, если параметр :secure установлен. Смотрите также remove_entry_secure.

rm_rf(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 653
def rm_rf(list, options = {})
  fu_check_options options, OPT_TABLE['rm_rf']
  options = options.dup
  options[:force] = true
  rm_r list, options
end

Параметры: noop verbose secure

Эквивалентно

#rm_r(list, :force => true)

ПРЕДУПРЕЖДЕНИЕ: Этот метод может привести к локальной уязвимости. Сначала ознакомьтесь с документацией метода rm_r.

Также алиас: rmtree
rmdir(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 268
def rmdir(list, options = {})
  fu_check_options options, OPT_TABLE['rmdir']
  list = fu_list(list)
  parents = options[:parents]
  fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if options[:verbose]
  return if options[:noop]
  list.each do |dir|
    begin
      Dir.rmdir(dir = remove_tailing_slash(dir))
      if parents
        until (parent = File.dirname(dir)) == '.' or parent == dir
          dir = parent
          Dir.rmdir(dir)
        end
      end
    rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
    end
  end
end

Удаляет один или несколько каталогов.

FileUtils.rmdir 'somedir'
FileUtils.rmdir %w(somedir anydir otherdir)
# Does not really remove directory; outputs message.
FileUtils.rmdir 'somedir', :verbose => true, :noop => true
rmtree(list, options = {})
Псевдоним для: rm_rf
safe_unlink(list, options = {})
Псевдоним для: rm_f
symlink(src, dest, options = {})
Псевдоним для: ln_s
touch(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 1142
def touch(list, options = {})
  fu_check_options options, OPT_TABLE['touch']
  list = fu_list(list)
  nocreate = options[:nocreate]
  t = options[:mtime]
  if options[:verbose]
    fu_output_message "touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}"
  end
  return if options[: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

Параметры: noop verbose mtime nocreate

Обновляет время изменения (mtime) и время доступа (atime) файла(ов) в list. Файлы создаются, если они не существуют.

FileUtils.touch 'timestamp'
FileUtils.touch Dir.glob('*.c');  system 'make'
uptodate?(new, old_list) Показать исходный код
# File lib/fileutils.rb, line 147
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

Возвращает true, если new новее всех old_list. Несуществующие файлы считаются старше любого файла.

FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or      system 'make hello.o'

Методы частного класса

collect_method(opt) Показать исходный код
# File lib/fileutils.rb, line 1671
def FileUtils.collect_method(opt)
  OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }
end

Возвращает массив имён методов, которые имеют параметр opt.

p FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
commands() Показать исходный код
# File lib/fileutils.rb, line 1632
def FileUtils.commands
  OPT_TABLE.keys
end

Возвращает массив имён методов, имеющих любые параметры.

p FileUtils.commands  #=> ["chmod", "cp", "cp_r", "install", ...]
have_option?(mid, opt) Показать исходный код
# File lib/fileutils.rb, line 1652
def FileUtils.have_option?(mid, opt)
  li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}"
  li.include?(opt)
end

Возвращает true, если метод mid имеет параметр opt.

p FileUtils.have_option?(:cp, :noop)     #=> true
p FileUtils.have_option?(:rm, :force)    #=> true
p FileUtils.have_option?(:rm, :preserve) #=> false
options() Показать исходный код
# File lib/fileutils.rb, line 1641
def FileUtils.options
  OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
end

Возвращает массив имён параметров.

p FileUtils.options  #=> ["noop", "force", "verbose", "preserve", "mode"]
options_of(mid) Показать исходный код
# File lib/fileutils.rb, line 1662
def FileUtils.options_of(mid)
  OPT_TABLE[mid.to_s].map {|sym| sym.to_s }
end

Возвращает массив имён параметров метода mid.

p FileUtils.options_of(:rm)  #=> ["noop", "verbose", "force"]

Публичные методы экземпляров

apply_mask(mode, user_mask, op, mode_mask) Показать исходный код
# File lib/fileutils.rb, line 892
def apply_mask(mode, user_mask, op, mode_mask)
  case op
  when '='
    (mode & ~user_mask) | (user_mask & mode_mask)
  when '+'
    mode | (user_mask & mode_mask)
  when '-'
    mode & ~(user_mask & mode_mask)
  end
end
remove_tailing_slash(dir) Показать исходный код
# File lib/fileutils.rb, line 159
def remove_tailing_slash(dir)
  dir == '/' ? dir : dir.chomp(?/)
end
ruby(*args, &block) Показать исходный код
# File lib/rake/file_utils.rb, line 91
def ruby(*args, &block)
  options = (Hash === args.last) ? args.pop : {}
  if args.length > 1
    sh(*([RUBY] + args + [options]), &block)
  else
    sh("#{RUBY} #{args.first}", options, &block)
  end
end

Запуск интерпретатора Ruby с заданными аргументами.

Пример:

ruby %Q{-pe '$_.upcase!' <README}
safe_ln(*args) Показать исходный код
# File lib/rake/file_utils.rb, line 104
def safe_ln(*args)
  if ! LN_SUPPORTED[0]
    cp(*args)
  else
    begin
      ln(*args)
    rescue StandardError, NotImplementedError
      LN_SUPPORTED[0] = false
      cp(*args)
    end
  end
end

Попытка создания обычной ссылки на файл, но при неудаче переходит к копированию.

sh(*cmd, &block) Показать исходный код
# File lib/rake/file_utils.rb, line 45
def sh(*cmd, &block)
  options = (Hash === cmd.last) ? cmd.pop : {}
  shell_runner = block_given? ? block : create_shell_runner(cmd)
  set_verbose_option(options)
  options[:noop] ||= Rake::FileUtilsExt.nowrite_flag
  Rake.rake_check_options options, :noop, :verbose
  Rake.rake_output_message cmd.join(" ") if options[:verbose]

  unless options[:noop]
    res = rake_system(*cmd)
    status = $?
    status = Rake::PseudoStatus.new(1) if !res && status.nil?
    shell_runner.call(res, status)
  end
end

Выполнение системной команды cmd. Если передано несколько аргументов, команда выполняется непосредственно (без оболочки, аналогично семантике Kernel::exec и Kernel::system).

Рекомендуется использовать форму с несколькими аргументами вместо интерполяции пользовательского ввода как по соображениям удобства, так и безопасности. С формой с несколькими аргументами вы легко можете обрабатывать файлы с пробелами или другими зарезервированными в оболочке символами. С формой с несколькими аргументами ваши задачи rake не уязвимы для пользователей, предоставляющих аргумент, такой как ; rm # -rf /.

Если блок задан, по завершении команды вызывается блок с флагом OK (true при нулевом коде возврата) и объектом Process::Status. Без блока при не нулевом коде возврата генерируется RuntimeError.

Примеры:

sh 'ls -ltr'

sh 'ls', 'file with spaces'

# check exit status after command runs
sh %Q{grep pattern file} do |ok, res|
  if ! ok
    puts "pattern not found (status = #{res.exitstatus})"
  end
end
split_all(path) Показать исходный код
# File lib/rake/file_utils.rb, line 122
def split_all(path)
  head, tail = File.split(path)
  return [tail] if head == '.' || tail == '/'
  return [head, tail] if head == '/'
  return split_all(head) + [tail]
end

Разделяет путь к файлу на отдельные имена каталогов.

Пример:

split_all("a/b/c") =>  ['a', 'b', 'c']

Методы частного экземпляра

cd(dir, options = {}) { |dir| ... } Показать исходный код
# File lib/fileutils.rb, line 124
def cd(dir, options = {}, &block) # :yield: dir
  fu_check_options options, OPT_TABLE['cd']
  fu_output_message "cd #{dir}" if options[:verbose]
  Dir.chdir(dir, &block)
  fu_output_message 'cd -' if options[:verbose] and block
end

Параметры: verbose

Изменяет текущую директорию на директорию dir.

Если этот метод вызывается с блоком, он возвращается в старую рабочую директорию после завершения выполнения блока.

FileUtils.cd('/', :verbose => true)   # chdir and report it

FileUtils.cd('/') do  # chdir
  [...]               # do something
end                   # return to original directory
Также алиасирован как: chdir
chdir(dir, options = {})
Псевдоним для: cd
chmod(mode, list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 994
def chmod(mode, list, options = {})
  fu_check_options options, OPT_TABLE['chmod']
  list = fu_list(list)
  fu_output_message sprintf('chmod %s %s', mode_to_s(mode), list.join(' ')) if options[:verbose]
  return if options[:noop]
  list.each do |path|
    Entry_.new(path).chmod(fu_mode(mode, path))
  end
end

Параметры: noop verbose

Изменяет биты разрешений для указанных файлов (в list) на битовую комбинацию, представленную mode.

Можно использовать символический и абсолютный режимы.

Абсолютный режим —

FileUtils.chmod 0755, 'somecommand'
FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true

Символический режим —

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”

является маской для пользователя, группы и других.

“u”

является маской пользователя.

“g”

является маской группы.

“o”

является маской для других.

“w”

является разрешением на запись.

“r”

является разрешением на чтение.

“x”

является разрешением на выполнение.

“X”

является разрешением на выполнение только для каталогов, должно использоваться в сочетании с “+”

“s”

является uid, gid.

“t”

является битом «sticky».

“+”

добавляется к классу, заданному указанным режимом.

“-”

удаляется из заданного класса, заданного режимом.

“=”

указывает точное состояние класса, заданного указанным режимом.

chmod_R(mode, list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 1016
def chmod_R(mode, list, options = {})
  fu_check_options options, OPT_TABLE['chmod_R']
  list = fu_list(list)
  fu_output_message sprintf('chmod -R%s %s %s',
                            (options[:force] ? 'f' : ''),
                            mode_to_s(mode), list.join(' ')) if options[:verbose]
  return if options[:noop]
  list.each do |root|
    Entry_.new(root).traverse do |ent|
      begin
        ent.chmod(fu_mode(mode, ent.path))
      rescue
        raise unless options[:force]
      end
    end
  end
end

Параметры: noop verbose force

Изменяет биты разрешений для указанных файлов (в list) на битовую комбинацию, представленную mode.

FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
chown(user, group, list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 1049
def chown(user, group, list, options = {})
  fu_check_options options, OPT_TABLE['chown']
  list = fu_list(list)
  fu_output_message sprintf('chown %s %s',
                            (group ? "#{user}:#{group}" : user || ':'),
                            list.join(' ')) if options[:verbose]
  return if options[:noop]
  uid = fu_get_uid(user)
  gid = fu_get_gid(group)
  list.each do |path|
    Entry_.new(path).chown uid, gid
  end
end

Параметры: noop verbose

Изменяет владельца и группу указанных файлов (в list) на пользователя user и группу group. user и group могут быть ID (целое число/строка) или именем (строка). Если user или group равно null, этот метод не изменяет атрибут.

FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true
chown_R(user, group, list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 1078
def chown_R(user, group, list, options = {})
  fu_check_options options, OPT_TABLE['chown_R']
  list = fu_list(list)
  fu_output_message sprintf('chown -R%s %s %s',
                            (options[:force] ? 'f' : ''),
                            (group ? "#{user}:#{group}" : user || ':'),
                            list.join(' ')) if options[:verbose]
  return if options[: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 options[:force]
      end
    end
  end
end

Параметры: noop verbose force

Рекурсивно изменяет владельца и группу указанных файлов (в list) на пользователя user и группу group. user и group могут быть ID (целое число/строка) или именем (строка). Если user или group равно null, этот метод не изменяет атрибут.

FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true
cmp(a, b)
Псевдоним для: compare_file
compare_file(a, b) Показать исходный код
# File lib/fileutils.rb, line 815
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

Возвращает true, если содержимое файла A и файла B идентичны.

FileUtils.compare_file('somefile', 'somefile')  #=> true
FileUtils.compare_file('/bin/cp', '/bin/mv')    #=> maybe false
Также алиасирован как: identical?, cmp
compare_stream(a, b) Показать исходный код
# File lib/fileutils.rb, line 833
def compare_stream(a, b)
  bsize = fu_stream_blksize(a, b)
  sa = ""
  sb = ""
  begin
    a.read(bsize, sa)
    b.read(bsize, sb)
    return true if sa.empty? && sb.empty?
  end while sa == sb
  false
end

Возвращает true, если содержимое потока a и b идентичны.

copy(src, dest, options = {})
Псевдоним для: cp
copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) Показать исходный код
# File lib/fileutils.rb, line 468
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
  Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    File.unlink destent.path if remove_destination && File.file?(destent.path)
    ent.copy destent.path
  end, proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    ent.copy_metadata destent.path if preserve
  end)
end

Копирует системный элемент src в dest. Если src — каталог, этот метод копирует его содержимое рекурсивно. Метод сохраняет типы файлов, например, символические ссылки, каталоги… (FIFO, файлы устройств и т. д. пока не поддерживаются)

И src, и dest должны быть именами путей. src должен существовать, dest не должен существовать.

Если preserve равно true, метод сохраняет владельца, группу и время изменения. Разрешения копируются независимо от preserve.

Если dereference_root равно true, этот метод дереференсирует корень дерева.

Если remove_destination равно true, этот метод удаляет каждый целевой файл перед копированием.

copy_file(src, dest, preserve = false, dereference = true) Показать исходный код
# File lib/fileutils.rb, line 484
def copy_file(src, dest, preserve = false, dereference = true)
  ent = Entry_.new(src, nil, dereference)
  ent.copy_file dest
  ent.copy_metadata dest if preserve
end

Копирует содержимое файла src в dest. И src, и dest должны быть именами путей.

copy_stream(src, dest) Показать исходный код
# File lib/fileutils.rb, line 496
def copy_stream(src, dest)
  IO.copy_stream(src, dest)
end

Копирует поток src в dest. src должен отвечать на read(n), а dest — на write(str).

cp(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 398
def cp(src, dest, options = {})
  fu_check_options options, OPT_TABLE['cp']
  fu_output_message "cp#{options[:preserve] ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest(src, dest) do |s, d|
    copy_file s, d, options[:preserve]
  end
end

Параметры: preserve noop verbose

Копирует содержимое файла src в dest. Если dest — каталог, копирует src в dest/src.

Если dest — список файлов, то dest должен быть каталогом.

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
Также алиасирован как: copy
cp_r(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 437
def cp_r(src, dest, options = {})
  fu_check_options options, OPT_TABLE['cp_r']
  fu_output_message "cp -r#{options[:preserve] ? 'p' : ''}#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  options = options.dup
  options[:dereference_root] = true unless options.key?(:dereference_root)
  fu_each_src_dest(src, dest) do |s, d|
    copy_entry s, d, options[:preserve], options[:dereference_root], options[:remove_destination]
  end
end

Параметры: preserve noop verbose dereference_root remove_destination

Копирует src в dest. Если src — каталог, этот метод рекурсивно копирует всё его содержимое. Если dest — каталог, копирует src в dest/src.

src может быть списком файлов.

# Installing Ruby library "mylib" under the site_ruby
FileUtils.rm_r site_ruby + '/mylib', :force
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/aamine/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.
getwd()
Псевдоним для: pwd
identical?(a, b)
Псевдоним для: compare_file
install(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 856
def install(src, dest, options = {})
  fu_check_options options, OPT_TABLE['install']
  fu_output_message "install -c#{options[:preserve] && ' -p'}#{options[:mode] ? (' -m 0%o' % options[:mode]) : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  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 options[:preserve]
      File.chmod options[:mode], d if options[:mode]
    end
  end
end

Параметры: mode preserve noop verbose

Если src не совпадает с dest, он копирует его и изменяет режим разрешений на mode. Если dest — каталог, место назначения — dest/src. Этот метод удаляет место назначения перед копированием.

FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
link(src, dest, options = {})
Псевдоним для: ln
ln(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 313
def ln(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln']
  fu_output_message "ln#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest0(src, dest) do |s,d|
    remove_file d, true if options[:force]
    File.link s, d
  end
end

Параметры: force noop verbose

ln(old, new, options = {})

Создаёт жёсткую ссылку new, которая указывает на old. Если new уже существует и это директория, создаёт ссылку new/old. Если new уже существует и это не директория, генерирует ошибку Errno::EEXIST. Но если установлен параметр :force, перезаписывает new.

FileUtils.ln 'gcc', 'cc', :verbose => true
FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'

ln(list, destdir, options = {})

Создаёт несколько жёстких ссылок в директории, каждая из которых указывает на элемент в list. Если destdir не является директорией, генерирует ошибку Errno::ENOTDIR.

include FileUtils
cd '/sbin'
FileUtils.ln %w(cp mv mkdir), '/bin'   # Now /sbin/cp and /bin/cp are linked.
Также псевдоним для: link
ln_s(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 352
def ln_s(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln_s']
  fu_output_message "ln -s#{options[:force] ? 'f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest0(src, dest) do |s,d|
    remove_file d, true if options[:force]
    File.symlink s, d
  end
end

Параметры: force noop verbose

ln_s(old, new, options = {})

Создаёт символическую ссылку new, которая указывает на old. Если new уже существует и это директория, создаёт символическую ссылку new/old. Если new уже существует и это не директория, генерирует ошибку Errno::EEXIST. Но если установлен параметр :force, перезаписывает new.

FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
FileUtils.ln_s 'verylongsourcefilename.c', 'c', :force => true

ln_s(list, destdir, options = {})

Создаёт несколько символических ссылок в директории, каждая из которых указывает на элемент в list. Если destdir не является директорией, генерирует ошибку Errno::ENOTDIR.

Если destdir не является директорией, генерирует ошибку Errno::ENOTDIR.

FileUtils.ln_s Dir.glob('bin/*.rb'), '/home/aamine/bin'
Также псевдоним для: symlink
ln_sf(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 375
def ln_sf(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln_sf']
  options = options.dup
  options[:force] = true
  ln_s src, dest, options
end

Параметры: noop verbose

То же, что и

#ln_s(src, dest, :force => true)
makedirs(list, options = {})
Псевдоним для: mkdir_p
mkdir(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 174
def mkdir(list, options = {})
  fu_check_options options, OPT_TABLE['mkdir']
  list = fu_list(list)
  fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
  return if options[:noop]

  list.each do |dir|
    fu_mkdir dir, options[:mode]
  end
end

Параметры: mode noop verbose

Создаёт одну или несколько директорий.

FileUtils.mkdir 'test'
FileUtils.mkdir %w( tmp data )
FileUtils.mkdir 'notexist', :noop => true  # Does not really create.
FileUtils.mkdir 'tmp', :mode => 0700
mkdir_p(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 204
def mkdir_p(list, options = {})
  fu_check_options options, OPT_TABLE['mkdir_p']
  list = fu_list(list)
  fu_output_message "mkdir -p #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
  return *list if options[:noop]

  list.map {|path| remove_tailing_slash(path)}.each do |path|
    # optimize for the most common case
    begin
      fu_mkdir path, options[: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, options[:mode]
      rescue SystemCallError
        raise unless File.directory?(dir)
      end
    end
  end

  return *list
end

Параметры: mode noop verbose

Создаёт директорию и все её родительские директории. Например,

FileUtils.mkdir_p '/usr/local/lib/ruby'

приводит к созданию следующих директорий, если они не существуют.

* /usr
* /usr/local
* /usr/local/lib
* /usr/local/lib/ruby

Можно передать несколько директорий одновременно в списке.

Также псевдоним для: mkpath, makedirs
mkpath(list, options = {})
Псевдоним для: mkdir_p
move(src, dest, options = {})
Псевдоним для: mv
mv(src, dest, options = {}) Показать исходный код
# File lib/fileutils.rb, line 513
def mv(src, dest, options = {})
  fu_check_options options, OPT_TABLE['mv']
  fu_output_message "mv#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[: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
        else
          destent.remove_file if rename_cannot_overwrite_file?
        end
      end
      begin
        File.rename s, d
      rescue Errno::EXDEV
        copy_entry s, d, true
        if options[:secure]
          remove_entry_secure s, options[:force]
        else
          remove_entry s, options[:force]
        end
      end
    rescue SystemCallError
      raise unless options[:force]
    end
  end
end

Параметры: force noop verbose

Перемещает файл(ы) src в dest. Если file и dest находятся на разных разделах диска, файл копируется, а затем исходный файл удаляется.

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/aamine/.trash/'
FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
Также псевдоним для: move
pwd() Показать исходный код
# File lib/fileutils.rb, line 102
def pwd
  Dir.pwd
end

Параметры: (нет)

Возвращает имя текущей директории.

Также псевдоним для: getwd
remove(list, options = {})
Псевдоним для: rm
remove_dir(path, force = false) Показать исходный код
# File lib/fileutils.rb, line 804
def remove_dir(path, force = false)
  remove_entry path, force   # FIXME?? check if it is a directory
end

Удаляет директорию dir и её содержимое рекурсивно. Этот метод игнорирует StandardError, если force равно true.

remove_entry(path, force = false) Показать исходный код
# File lib/fileutils.rb, line 776
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

Этот метод удаляет элемент файловой системы path. path может быть обычным файлом, директорией или чем-то ещё. Если path является директорией, удаляет её рекурсивно.

См. также remove_entry_secure.

remove_entry_secure(path, force = false) Показать исходный код
# File lib/fileutils.rb, line 699
def remove_entry_secure(path, force = false)
  unless fu_have_symlink?
    remove_entry path, force
    return
  end
  fullpath = File.expand_path(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
  File.open(fullpath + '/.') {|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
    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

Этот метод удаляет элемент файловой системы path. path должен быть обычным файлом, директорией или чем-то ещё. Если path является директорией, удаляет её рекурсивно. Этот метод необходим для предотвращения уязвимости TOCTTOU (time-of-check-to-time-of-use) локальной безопасности метода rm_r. rm_r может привести к уязвимости, когда:

* Parent directory is world writable (including /tmp).
* Removing directory tree includes world writable directory.
* The system has symbolic link.

Чтобы избежать этой уязвимости, этот метод применяет специальную предобработку. Если path является директорией, этот метод использует chown(2) и chmod(2) для всех удаляемых директорий. Это требует, чтобы текущий процесс был владельцем удаляемой всей древовидной структуры директорий или был суперпользователем (root).

ВНИМАНИЕ: Вы должны убедиться, что ВСЕ родительские директории недоступны для перемещения другими неуверенными пользователями. Например, родительские директории не должны принадлежать неуверенным пользователям и не должны быть доступны для записи всем, кроме случаев, когда установлен бит «вклейки».

ВНИМАНИЕ: Только владелец удаляемой древовидной структуры директорий или Unix-суперпользователь (root) должен вызывать этот метод. В противном случае этот метод не сработает.

Для получения подробностей об этой уязвимости см. пример Perl:

http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452

Для fileutils.rb эта уязвимость была сообщена в [ruby-dev:26100].

remove_file(path, force = false) Показать исходный код
# File lib/fileutils.rb, line 793
def remove_file(path, force = false)
  Entry_.new(path).remove_file
rescue
  raise unless force
end

Удаляет файл path. Этот метод игнорирует StandardError, если force равно true.

rm(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 565
def rm(list, options = {})
  fu_check_options options, OPT_TABLE['rm']
  list = fu_list(list)
  fu_output_message "rm#{options[:force] ? ' -f' : ''} #{list.join ' '}" if options[:verbose]
  return if options[:noop]

  list.each do |path|
    remove_file path, options[:force]
  end
end

Параметры: force noop verbose

Удаляет файлы, указанные в list. Этот метод не может удалять директории. Все StandardErrors игнорируются, когда установлен параметр :force.

FileUtils.rm %w( junk.txt dust.txt )
FileUtils.rm Dir.glob('*.so')
FileUtils.rm 'NotExistFile', :force => true   # never raises exception
Также псевдоним для: remove
rm_f(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 590
def rm_f(list, options = {})
  fu_check_options options, OPT_TABLE['rm_f']
  options = options.dup
  options[:force] = true
  rm list, options
end

Параметры: noop verbose

Эквивалентно

#rm(list, :force => true)
Также псевдоним для: safe_unlink
END_OF_DOCUMENT_MARKER
rm_r(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 625
def rm_r(list, options = {})
  fu_check_options options, OPT_TABLE['rm_r']
  # options[:secure] = true unless options.key?(:secure)
  list = fu_list(list)
  fu_output_message "rm -r#{options[:force] ? 'f' : ''} #{list.join ' '}" if options[:verbose]
  return if options[:noop]
  list.each do |path|
    if options[:secure]
      remove_entry_secure path, options[:force]
    else
      remove_entry path, options[:force]
    end
  end
end

Параметры: force noop verbose secure

Удаляет файлы list[0] list[1]… Если list[n] является каталогом, удаляет все его содержимое рекурсивно. Этот метод игнорирует StandardError при установке параметра :force.

FileUtils.rm_r Dir.glob('/tmp/*')
FileUtils.rm_r '/', :force => true          #  :-)

ВНИМАНИЕ: Этот метод может привести к локальной уязвимости, если один из родительских каталогов или удаляемая директория имеют права доступа для всех (включая /tmp, чьи права доступа составляют 1777), а текущий процесс обладает сильными привилегиями, такими как суперпользователь Unix (root), и на системе имеются символические ссылки. Для безопасного удаления, внимательно изучите документацию remove_entry_secure и установите параметр :secure в значение true. По умолчанию :secure=>false.

ПРИМЕЧАНИЕ: Этот метод вызывает remove_entry_secure, если установлен параметр :secure. См. также remove_entry_secure.

rm_rf(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 653
def rm_rf(list, options = {})
  fu_check_options options, OPT_TABLE['rm_rf']
  options = options.dup
  options[:force] = true
  rm_r list, options
end

Параметры: noop verbose secure

Эквивалентно

#rm_r(list, :force => true)

ВНИМАНИЕ: Этот метод может привести к локальной уязвимости. Сначала прочитайте документацию rm_r.

Также алиас: rmtree
rmdir(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 268
def rmdir(list, options = {})
  fu_check_options options, OPT_TABLE['rmdir']
  list = fu_list(list)
  parents = options[:parents]
  fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if options[:verbose]
  return if options[:noop]
  list.each do |dir|
    begin
      Dir.rmdir(dir = remove_tailing_slash(dir))
      if parents
        until (parent = File.dirname(dir)) == '.' or parent == dir
          dir = parent
          Dir.rmdir(dir)
        end
      end
    rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
    end
  end
end

Параметры: parents, noop, verbose

Удаляет один или несколько каталогов.

FileUtils.rmdir 'somedir'
FileUtils.rmdir %w(somedir anydir otherdir)
# Does not really remove directory; outputs message.
FileUtils.rmdir 'somedir', :verbose => true, :noop => true
rmtree(list, options = {})
Псевдоним для: rm_rf
safe_unlink(list, options = {})
Псевдоним для: rm_f
symlink(src, dest, options = {})
Псевдоним для: ln_s
touch(list, options = {}) Показать исходный код
# File lib/fileutils.rb, line 1142
def touch(list, options = {})
  fu_check_options options, OPT_TABLE['touch']
  list = fu_list(list)
  nocreate = options[:nocreate]
  t = options[:mtime]
  if options[:verbose]
    fu_output_message "touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}"
  end
  return if options[: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

Параметры: noop verbose mtime nocreate

Обновляет время изменения (mtime) и время доступа (atime) файла(ов) в list. Файлы создаются, если они не существуют.

FileUtils.touch 'timestamp'
FileUtils.touch Dir.glob('*.c');  system 'make'
uptodate?(new, old_list) Показать исходный код
# File lib/fileutils.rb, line 147
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

Параметры: (нет)

Возвращает true, если new новее всех old_list. Несуществующие файлы считаются старше любого файла.

FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or      system 'make hello.o'

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API