Spec-Zone.ru › Ruby 2.6

модуль Bundler::FileUtils

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

fileutils.rb

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

Данная программа является свободной программной. Вы можете распространять/модифицировать данную программу в соответствии с условиями ruby.

модуль Bundler::FileUtils

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

Module Функции

require 'bundler/vendor/fileutils/lib/fileutils'

Bundler::FileUtils.cd(dir, options)
Bundler::FileUtils.cd(dir, options) {|dir| block }
Bundler::FileUtils.pwd()
Bundler::FileUtils.mkdir(dir, options)
Bundler::FileUtils.mkdir(list, options)
Bundler::FileUtils.mkdir_p(dir, options)
Bundler::FileUtils.mkdir_p(list, options)
Bundler::FileUtils.rmdir(dir, options)
Bundler::FileUtils.rmdir(list, options)
Bundler::FileUtils.ln(target, link, options)
Bundler::FileUtils.ln(targets, dir, options)
Bundler::FileUtils.ln_s(target, link, options)
Bundler::FileUtils.ln_s(targets, dir, options)
Bundler::FileUtils.ln_sf(target, link, options)
Bundler::FileUtils.cp(src, dest, options)
Bundler::FileUtils.cp(list, dir, options)
Bundler::FileUtils.cp_r(src, dest, options)
Bundler::FileUtils.cp_r(list, dir, options)
Bundler::FileUtils.mv(src, dest, options)
Bundler::FileUtils.mv(list, dir, options)
Bundler::FileUtils.rm(list, options)
Bundler::FileUtils.rm_r(list, options)
Bundler::FileUtils.rm_rf(list, options)
Bundler::FileUtils.install(src, dest, options)
Bundler::FileUtils.chmod(mode, list, options)
Bundler::FileUtils.chmod_R(mode, list, options)
Bundler::FileUtils.chown(user, group, list, options)
Bundler::FileUtils.chown_R(user, group, list, options)
Bundler::FileUtils.touch(list, options)

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

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

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

Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference = false)
Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true)
Bundler::FileUtils.copy_stream(srcstream, deststream)
Bundler::FileUtils.remove_entry(path, force = false)
Bundler::FileUtils.remove_entry_secure(path, force = false)
Bundler::FileUtils.remove_file(path, force = false)
Bundler::FileUtils.compare_file(path_a, path_b)
Bundler::FileUtils.compare_stream(stream_a, stream_b)
Bundler::FileUtils.uptodate?(file, cmp_list)

модуль Bundler::FileUtils::Verbose

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

модуль Bundler::FileUtils::NoWrite

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

модуль Bundler::FileUtils::DryRun

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

Константы

LOW_METHODS
METHODS

Методы публичного класса

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

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

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

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

Bundler::FileUtils.cd('/') do  # chdir
  # ...               # do something
end                   # return to original directory
Также известен как: chdir
chdir(dir, verbose: nil)
Псевдоним для: cd
chmod(mode, list, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 914
def chmod(mode, list, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message 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

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

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

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

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

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

Bundler::FileUtils.chmod "u=wrx,go=rx", 'somecommand'
Bundler::FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
Bundler::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, noop: nil, verbose: nil, force: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 931
def chmod_R(mode, list, noop: nil, verbose: nil, force: nil)
  list = fu_list(list)
  fu_output_message 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

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

Bundler::FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
Bundler::FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
chown(user, group, list, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 959
def chown(user, group, list, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message 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

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

Bundler::FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true
chown_R(user, group, list, noop: nil, verbose: nil, force: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 983
def chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
  list = fu_list(list)
  fu_output_message 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

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

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

Bundler::FileUtils.compare_file('somefile', 'somefile')       #=> true
Bundler::FileUtils.compare_file('/dev/null', '/dev/urandom')  #=> false
Также известен как: identical?, cmp
compare_stream(a, b) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 743
def compare_stream(a, b)
  bsize = fu_stream_blksize(a, b)
  sa = String.new(capacity: bsize)
  sb = String.new(capacity: bsize)
  begin
    a.read(bsize, sa)
    b.read(bsize, sb)
    return true if sa.empty? && sb.empty?
  end while sa == sb
  false
end

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

copy(src, dest, preserve: nil, noop: nil, verbose: nil)
Псевдоним для: cp
copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 412
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/bundler/vendor/fileutils/lib/fileutils.rb, line 428
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/bundler/vendor/fileutils/lib/fileutils.rb, line 440
def copy_stream(src, dest)
  IO.copy_stream(src, dest)
end

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

cp(src, dest, preserve: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 353
def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
  fu_output_message "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

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

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

Bundler::FileUtils.cp 'eval.c', 'eval.c.org'
Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true
Bundler::FileUtils.cp 'symlink', 'dest'   # copy content, "dest" is not a symlink
Также известен как: copy
cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 386
def cp_r(src, dest, preserve: nil, noop: nil, verbose: nil,
         dereference_root: true, remove_destination: nil)
  fu_output_message "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

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

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

# Installing Ruby library "mylib" under the site_ruby
Bundler::FileUtils.rm_r site_ruby + '/mylib', :force
Bundler::FileUtils.cp_r 'lib/', site_ruby + '/mylib'

# Examples of copying several files to target directory.
Bundler::FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
Bundler::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.
Bundler::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, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 764
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(' ')
    fu_output_message 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

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

Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
END_OF_DOCUMENT_MARKER
link(src, dest, force: nil, noop: nil, verbose: nil)
Alias for: ln
Bundler::FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil) Показать исходный код
Bundler::FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil)
Bundler::FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil)
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 283
def ln(src, dest, force: nil, noop: nil, verbose: nil)
  fu_output_message "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, которая указывает на target. Если link уже существует, возникает исключение Errno::EEXIST. Но если установлен параметр :force, link перезаписывается.

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

Во втором варианте создаётся ссылка dir/target , указывающая на target. В третьем варианте создаются несколько жёстких ссылок в каталоге dir, указывающих на каждый элемент в targets. Если dir не является каталогом, возникает исключение Errno::ENOTDIR.

Bundler::FileUtils.cd '/sbin'
Bundler::FileUtils.ln %w(cp mv mkdir), '/bin'   # Now /sbin/cp and /bin/cp are linked.
Также алиас для: link
Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil) Показать исходный код
Bundler::FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
Bundler::FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil)
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 316
def ln_s(src, dest, force: nil, noop: nil, verbose: nil)
  fu_output_message "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

В первом варианте создаёт символическую ссылку link, которая указывает на target. Если link уже существует, возникает исключение Errno::EEXIST. Но если установлен параметр :force, link перезаписывается.

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

Во втором варианте создаётся ссылка dir/target , указывающая на target. В третьем варианте создаются несколько символических ссылок в каталоге dir, указывающих на каждый элемент в targets. Если dir не является каталогом, возникает исключение Errno::ENOTDIR.

Bundler::FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin'
Также алиас для: symlink
Bundler::FileUtils.ln_sf(*args) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 337
def ln_sf(src, dest, noop: nil, verbose: nil)
  ln_s src, dest, force: true, noop: noop, verbose: verbose
end

То же самое, что и

Bundler::FileUtils.ln_s(*args, force: true)
makedirs(list, mode: nil, noop: nil, verbose: nil)
Alias for: mkdir_p
mkdir(list, mode: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 160
def mkdir(list, mode: nil, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message "mkdir #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose
  return if noop

  list.each do |dir|
    fu_mkdir dir, mode
  end
end

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

Bundler::FileUtils.mkdir 'test'
Bundler::FileUtils.mkdir %w( tmp data )
Bundler::FileUtils.mkdir 'notexist', :noop => true  # Does not really create.
Bundler::FileUtils.mkdir 'tmp', :mode => 0700
mkdir_p(list, mode: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 186
def mkdir_p(list, mode: nil, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message "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

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

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

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

  • /usr

  • /usr/local

  • /usr/local/lib

  • /usr/local/lib/ruby

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

Также алиас для: mkpath, makedirs
mkpath(list, mode: nil, noop: nil, verbose: nil)
Alias for: mkdir_p
move(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
Alias for: mv
mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 455
def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
  fu_output_message "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
        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 secure
          remove_entry_secure s, force
        else
          remove_entry s, force
        end
      end
    rescue SystemCallError
      raise unless force
    end
  end
end

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

Bundler::FileUtils.mv 'badname.rb', 'goodname.rb'
Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true  # no error

Bundler::FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
Также алиас для: move
pwd() Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 98
def pwd
  Dir.pwd
end

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

Также алиас для: getwd
remove(list, force: nil, noop: nil, verbose: nil)
Alias for: rm
remove_dir(path, force = false) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 714
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/bundler/vendor/fileutils/lib/fileutils.rb, line 686
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/bundler/vendor/fileutils/lib/fileutils.rb, line 609
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, Bundler::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 создаёт дыру в безопасности, когда:

  • Родительский каталог имеет разрешение на запись для всех (включая /tmp).

  • Удаляемая древовидная структура каталогов включает каталог с разрешением на запись для всех.

  • В системе есть символические ссылки.

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

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

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

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

  • www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448

  • www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452

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

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

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

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

  list.each do |path|
    remove_file path, force
  end
end

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

Bundler::FileUtils.rm %w( junk.txt dust.txt )
Bundler::FileUtils.rm Dir.glob('*.so')
Bundler::FileUtils.rm 'NotExistFile', :force => true   # never raises exception
Также алиасируется как: remove
rm_f(list, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 520
def rm_f(list, noop: nil, verbose: nil)
  rm list, force: true, noop: noop, verbose: verbose
end

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

Bundler::FileUtils.rm(list, :force => true)
Также алиасируется как: safe_unlink
rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 547
def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
  list = fu_list(list)
  fu_output_message "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

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

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

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

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

rm_rf(list, noop: nil, verbose: nil, secure: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 569
def rm_rf(list, noop: nil, verbose: nil, secure: nil)
  rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
end

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

Bundler::FileUtils.rm_r(list, :force => true)

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

Также алиасируется как: rmtree
rmdir(list, parents: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 243
def rmdir(list, parents: nil, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
  return if noop
  list.each do |dir|
    begin
      Dir.rmdir(dir = remove_trailing_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

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

Bundler::FileUtils.rmdir 'somedir'
Bundler::FileUtils.rmdir %w(somedir anydir otherdir)
# Does not really remove directory; outputs message.
Bundler::FileUtils.rmdir 'somedir', :verbose => true, :noop => true
rmtree(list, noop: nil, verbose: nil, secure: nil)
Псевдоним для: rm_rf
safe_unlink(list, noop: nil, verbose: nil)
Псевдоним для: rm_f
symlink(src, dest, force: nil, noop: nil, verbose: nil)
Псевдоним для: ln_s
touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 1042
def touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
  list = fu_list(list)
  t = mtime
  if verbose
    fu_output_message "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

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

Bundler::FileUtils.touch 'timestamp'
Bundler::FileUtils.touch Dir.glob('*.c');  system 'make'
uptodate?(new, old_list) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 135
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. Несуществующие файлы старше любого файла.

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

Методы класса (private)

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

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

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

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

p Bundler::FileUtils.commands  #=> ["chmod", "cp", "cp_r", "install", ...]
have_option?(mid, opt) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 1530
def self.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 Bundler::FileUtils.have_option?(:cp, :noop)     #=> true
p Bundler::FileUtils.have_option?(:rm, :force)    #=> true
p Bundler::FileUtils.have_option?(:rm, :preserve) #=> false
options() Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 1519
def self.options
  OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
end

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

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

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

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

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

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

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

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

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

Bundler::FileUtils.cd('/') do  # chdir
  # ...               # do something
end                   # return to original directory
Также известен как: chdir
chdir(dir, verbose: nil)
Псевдоним для: cd
chmod(mode, list, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 914
def chmod(mode, list, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message 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

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

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

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

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

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

Bundler::FileUtils.chmod "u=wrx,go=rx", 'somecommand'
Bundler::FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
Bundler::FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', :verbose => true
“a”

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

“u”

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

“g”

маска группы.

“o”

маска других.

“w”

разрешение на запись.

“r”

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

“x”

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

“X”

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

“s”

uid, gid.

“t”

разрешение "sticky bit".

“+”

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

“-”

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

“=”

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

chmod_R(mode, list, noop: nil, verbose: nil, force: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 931
def chmod_R(mode, list, noop: nil, verbose: nil, force: nil)
  list = fu_list(list)
  fu_output_message 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

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

Bundler::FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
Bundler::FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
chown(user, group, list, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 959
def chown(user, group, list, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message 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

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

Bundler::FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true
chown_R(user, group, list, noop: nil, verbose: nil, force: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 983
def chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
  list = fu_list(list)
  fu_output_message 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

Рекурсивно изменяет владельца и группу указанных файлов (в list) на пользователя user и группу group.

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

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

Bundler::FileUtils.compare_file('somefile', 'somefile')       #=> true
Bundler::FileUtils.compare_file('/dev/null', '/dev/urandom')  #=> false
Также известен как: identical?, cmp
compare_stream(a, b) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 743
def compare_stream(a, b)
  bsize = fu_stream_blksize(a, b)
  sa = String.new(capacity: bsize)
  sb = String.new(capacity: bsize)
  begin
    a.read(bsize, sa)
    b.read(bsize, sb)
    return true if sa.empty? && sb.empty?
  end while sa == sb
  false
end

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

copy(src, dest, preserve: nil, noop: nil, verbose: nil)
Псевдоним для: cp
copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 412
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/bundler/vendor/fileutils/lib/fileutils.rb, line 428
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/bundler/vendor/fileutils/lib/fileutils.rb, line 440
def copy_stream(src, dest)
  IO.copy_stream(src, dest)
end

Копирует поток src в dest.

src должен отвечать на read(n), а dest должен отвечать на write(str).

cp(src, dest, preserve: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 353
def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
  fu_output_message "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

Копирует содержимое файла src в dest.

Если dest — это каталог, копирует src в dest/src.

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

Bundler::FileUtils.cp 'eval.c', 'eval.c.org'
Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true
Bundler::FileUtils.cp 'symlink', 'dest'   # copy content, "dest" is not a symlink
Также известен как: copy
cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 386
def cp_r(src, dest, preserve: nil, noop: nil, verbose: nil,
         dereference_root: true, remove_destination: nil)
  fu_output_message "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

Копирует src в dest.

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

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

# Installing Ruby library "mylib" under the site_ruby
Bundler::FileUtils.rm_r site_ruby + '/mylib', :force
Bundler::FileUtils.cp_r 'lib/', site_ruby + '/mylib'

# Examples of copying several files to target directory.
Bundler::FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
Bundler::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.
Bundler::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, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 764
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(' ')
    fu_output_message 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

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

Если dest — это каталог, назначение — dest/src.

Метод удаляет назначение перед копированием.

Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
END_OF_DOCUMENT_MARKER
link(src, dest, force: nil, noop: nil, verbose: nil)
Псевдоним для: ln
Bundler::FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil) Показать исходный код
Bundler::FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil)
Bundler::FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil)
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 283
def ln(src, dest, force: nil, noop: nil, verbose: nil)
  fu_output_message "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, которая указывает на target. Если link уже существует, генерируется исключение Errno::EEXIST. Но если установлен параметр :force, link перезаписывается.

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

Во втором случае создаётся ссылка dir/target, указывающая на target. В третьем случае создаётся несколько жёстких ссылок в каталоге dir, указывающих на каждый элемент в targets. Если dir не является каталогом, генерируется исключение Errno::ENOTDIR.

Bundler::FileUtils.cd '/sbin'
Bundler::FileUtils.ln %w(cp mv mkdir), '/bin'   # Now /sbin/cp and /bin/cp are linked.
Также псевдоним для: link
Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil) Показать исходный код
Bundler::FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
Bundler::FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil)
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 316
def ln_s(src, dest, force: nil, noop: nil, verbose: nil)
  fu_output_message "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

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

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

Во втором случае создаётся ссылка dir/target, указывающая на target. В третьем случае создаётся несколько символических ссылок в каталоге dir, указывающих на каждый элемент в targets. Если dir не является каталогом, генерируется исключение Errno::ENOTDIR.

Bundler::FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin'
Также псевдоним для: symlink
Bundler::FileUtils.ln_sf(*args) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 337
def ln_sf(src, dest, noop: nil, verbose: nil)
  ln_s src, dest, force: true, noop: noop, verbose: verbose
end

То же, что и

Bundler::FileUtils.ln_s(*args, force: true)
makedirs(list, mode: nil, noop: nil, verbose: nil)
Псевдоним для: mkdir_p
mkdir(list, mode: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 160
def mkdir(list, mode: nil, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message "mkdir #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose
  return if noop

  list.each do |dir|
    fu_mkdir dir, mode
  end
end

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

Bundler::FileUtils.mkdir 'test'
Bundler::FileUtils.mkdir %w( tmp data )
Bundler::FileUtils.mkdir 'notexist', :noop => true  # Does not really create.
Bundler::FileUtils.mkdir 'tmp', :mode => 0700
mkdir_p(list, mode: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 186
def mkdir_p(list, mode: nil, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message "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

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

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

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

  • /usr

  • /usr/local

  • /usr/local/lib

  • /usr/local/lib/ruby

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

Также псевдоним для: mkpath, makedirs
mkpath(list, mode: nil, noop: nil, verbose: nil)
Псевдоним для: mkdir_p
move(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
Псевдоним для: mv
mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 455
def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
  fu_output_message "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
        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 secure
          remove_entry_secure s, force
        else
          remove_entry s, force
        end
      end
    rescue SystemCallError
      raise unless force
    end
  end
end

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

Bundler::FileUtils.mv 'badname.rb', 'goodname.rb'
Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true  # no error

Bundler::FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
Также псевдоним для: move
pwd() Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 98
def pwd
  Dir.pwd
end

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

Также псевдоним для: getwd
remove(list, force: nil, noop: nil, verbose: nil)
Псевдоним для: rm
remove_dir(path, force = false) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 714
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/bundler/vendor/fileutils/lib/fileutils.rb, line 686
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/bundler/vendor/fileutils/lib/fileutils.rb, line 609
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, Bundler::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 создаёт брешь в безопасности, когда:

  • Родительский каталог имеет права записи для всех (включая /tmp).

  • Удаляемая древовидная структура каталогов включает каталог с правами записи для всех.

  • В системе есть символические ссылки.

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

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

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

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

  • www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448

  • www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452

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

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

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

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

  list.each do |path|
    remove_file path, force
  end
end

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

Bundler::FileUtils.rm %w( junk.txt dust.txt )
Bundler::FileUtils.rm Dir.glob('*.so')
Bundler::FileUtils.rm 'NotExistFile', :force => true   # never raises exception
Также алиас для: remove
rm_f(list, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 520
def rm_f(list, noop: nil, verbose: nil)
  rm list, force: true, noop: noop, verbose: verbose
end

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

Bundler::FileUtils.rm(list, :force => true)
Также алиас для: safe_unlink
rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 547
def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
  list = fu_list(list)
  fu_output_message "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

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

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

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

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

rm_rf(list, noop: nil, verbose: nil, secure: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 569
def rm_rf(list, noop: nil, verbose: nil, secure: nil)
  rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
end

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

Bundler::FileUtils.rm_r(list, :force => true)

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

Также алиас для: rmtree
rmdir(list, parents: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 243
def rmdir(list, parents: nil, noop: nil, verbose: nil)
  list = fu_list(list)
  fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
  return if noop
  list.each do |dir|
    begin
      Dir.rmdir(dir = remove_trailing_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

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

Bundler::FileUtils.rmdir 'somedir'
Bundler::FileUtils.rmdir %w(somedir anydir otherdir)
# Does not really remove directory; outputs message.
Bundler::FileUtils.rmdir 'somedir', :verbose => true, :noop => true
rmtree(list, noop: nil, verbose: nil, secure: nil)
Псевдоним для: rm_rf
safe_unlink(list, noop: nil, verbose: nil)
Псевдоним для: rm_f
symlink(src, dest, force: nil, noop: nil, verbose: nil)
Псевдоним для: ln_s
touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 1042
def touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
  list = fu_list(list)
  t = mtime
  if verbose
    fu_output_message "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

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

Bundler::FileUtils.touch 'timestamp'
Bundler::FileUtils.touch Dir.glob('*.c');  system 'make'
uptodate?(new, old_list) Показать исходный код
# File lib/bundler/vendor/fileutils/lib/fileutils.rb, line 135
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. Несуществующие файлы считаются более старыми, чем любой другой файл.

Bundler::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