Spec-Zone.ru › Ruby 4.0

модуль FileUtils

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

Что здесь

Сначала — о том, что находится в другом месте. Модуль FileUtils:

  • Наследуется от класса Object.

  • Дополняет класс File (но не включается и не расширяется в нём).

Здесь модуль FileUtils предоставляет методы, полезные для:

  • Создания.

  • Удаления.

  • Запроса информации.

  • Установки параметров.

  • Сравнения.

  • Копирования.

  • Перемещения.

  • Параметров.

Создание

  • ::mkdir: Создаёт каталоги.

  • ::mkdir_p, ::makedirs, ::mkpath: Создаёт каталоги, при необходимости создавая также родительские каталоги.

  • ::link_entry: Создаёт жёсткую ссылку.

  • ::ln, ::link: Создаёт жёсткие ссылки.

  • ::ln_s, ::symlink: Создаёт символические ссылки.

  • ::ln_sf: Создаёт символические ссылки, при необходимости перезаписывая существующие.

  • ::ln_sr: Создаёт символические ссылки, относительные к целевым объектам.

Удаление

  • ::remove_dir: Удаляет каталог и его содержимое.

  • ::remove_entry: Удаляет элемент, включая его содержимое, если это каталог.

  • ::remove_entry_secure: Подобно ::remove_entry, но выполняет безопасное удаление.

  • ::remove_file: Удаляет файловый элемент.

  • ::rm, ::remove: Удаляет элементы.

  • ::rm_f, ::safe_unlink: Подобно ::rm, но выполняет принудительное удаление.

  • ::rm_r: Удаляет элементы и их содержимое.

  • ::rm_rf, ::rmtree: Подобно ::rm_r, но выполняет принудительное удаление.

  • ::rmdir: Удаляет каталоги.

Запрос информации

  • ::pwd, ::getwd: Возвращает путь к рабочему каталогу.

  • ::uptodate?: Возвращает, является ли данный элемент более новым, чем указанные другие элементы.

Установка параметров

  • ::cd, ::chdir: Устанавливает рабочий каталог.

  • ::chmod: Устанавливает права доступа для элемента.

  • ::chmod_R: Устанавливает права доступа для элемента и его содержимого.

  • ::chown: Устанавливает владельца и группу для элементов.

  • ::chown_R: Устанавливает владельца и группу для элементов и их содержимого.

  • ::touch: Устанавливает время изменения и доступа для элементов, при необходимости создавая их.

Сравнение

  • ::compare_file, ::cmp, ::identical?: Возвращает, идентичны ли два элемента.

  • ::compare_stream: Возвращает, идентичны ли два потока.

Копирование

  • ::copy_entry: Рекурсивно копирует элемент.

  • ::copy_file: Копирует элемент.

  • ::copy_stream: Копирует поток.

  • ::cp, ::copy: Копирует файлы.

  • ::cp_lr: Рекурсивно создаёт жёсткие ссылки.

  • ::cp_r: Рекурсивно копирует файлы, сохраняя режим доступа, владельца и группу.

  • ::install: Рекурсивно копирует файлы, при необходимости задавая режим доступа, владельца и группу.

Перемещение

  • ::mv, ::move: Перемещает элементы.

Параметры

  • ::collect_method: Возвращает имена методов, принимающих указанный параметр.

  • ::commands: Возвращает имена методов, принимающих параметры.

  • ::have_option?: Возвращает, принимает ли указанный метод указанный параметр.

  • ::options: Возвращает имена всех параметров.

  • ::options_of: Возвращает имена параметров указанного метода.

Аргументы-пути

Некоторые методы FileUtils принимают аргументы path, которые интерпретируются как пути к элементам файловой системы:

  • Если аргумент является строкой, её значение используется как путь.

  • Если у аргумента есть метод :to_path, он преобразуется с помощью этого метода.

  • Если у аргумента есть метод :to_str, он преобразуется с помощью этого метода.

Об этих примерах

Некоторые примеры здесь посвящены деревьям файловых элементов. В таких случаях мы иногда показываем деревья с помощью утилиты командной строки tree — утилиты для рекурсивного просмотра каталогов, которая выводит список файлов и каталогов с отступами, отражающими глубину вложенности.

Для запуска команды и управления форматом мы используем вспомогательный метод:

def tree(dirpath = '.')
  command = "tree --noreport --charset=ascii #{dirpath}"
  system(command)
end

Например:

tree('src0')
# => src0
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt

Защита от уязвимости TOCTTOU

Для некоторых методов, рекурсивно удаляющих элементы, существует потенциальная уязвимость, называемая уязвимостью «время проверки — время использования» (Time-of-check to time-of-use), или TOCTTOU. Она может возникнуть, когда:

  • Каталог-предок элемента по целевому пути доступен для записи всем пользователям; к таким каталогам относится /tmp.

  • Дерево каталогов по целевому пути содержит:

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

    • Символическую ссылку.

Чтобы избежать этой уязвимости, для удаления элементов можно использовать следующий метод:

  • FileUtils.remove_entry_secure: выполняет рекурсивное удаление, если целевой путь указывает на каталог.

Также доступны следующие методы, каждый из которых вызывает FileUtils.remove_entry_secure:

  • FileUtils.rm_r с именованным аргументом secure: true.

  • FileUtils.rm_rf с именованным аргументом secure: true.

Наконец, следующий метод перемещения элементов вызывает FileUtils.remove_entry_secure, если исходный и целевой элементы находятся в разных файловых системах (то есть «перемещение» фактически выполняется как копирование с последующим удалением):

  • FileUtils.mv с именованным аргументом secure: true.

Метод FileUtils.remove_entry_secure обеспечивает безопасное удаление с помощью специальной предварительной обработки:

  • Если целевой путь указывает на каталог, этот метод использует методы File#chown и File#chmod при удалении каталогов.

  • Владельцем целевого каталога должен быть текущий процесс или суперпользователь (root).

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

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

  • CVE-2005-0448.

  • CVE-2004-0452.

Константы

VERSION

Номер версии.

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

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

Изменяет рабочий каталог на заданный dir, который должен быть интерпретируем как путь:

Если блок не задан, изменяет текущий каталог на каталог по адресу dir; возвращает ноль:

FileUtils.pwd # => "/rdoc/fileutils"
FileUtils.cd('..')
FileUtils.pwd # => "/rdoc"
FileUtils.cd('fileutils')

Если блок задан, изменяет текущий каталог на каталог по адресу dir, вызывает блок с аргументом dir и восстанавливает исходный текущий каталог; возвращает значение блока:

FileUtils.pwd                                     # => "/rdoc/fileutils"
FileUtils.cd('..') { |arg| [arg, FileUtils.pwd] } # => ["..", "/rdoc"]
FileUtils.pwd                                     # => "/rdoc/fileutils"

Именованные аргументы:

  • verbose: true — выводит эквивалентную команду:

    FileUtils.cd('..')
    FileUtils.cd('fileutils')
    

    Вывод:

    cd ..
    cd fileutils

Связанный метод: FileUtils.pwd.

Также имеет псевдоним: chdir
chdir (dir, verbose: nil)
Псевдоним для: cd
chmod (mode, list, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1801
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; возвращает list, если это массив, и [list] в противном случае:

  • Изменяет каждый элемент, являющийся обычным файлом, с помощью File.chmod.

  • Изменяет каждый элемент, являющийся символической ссылкой, с помощью File.lchmod.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Аргумент mode может быть целым числом или строкой:

  • Целое число mode: представляет биты разрешений, которые нужно установить:

    FileUtils.chmod(0755, 'src0.txt')
    FileUtils.chmod(0644, ['src0.txt', 'src0.dat'])
    
  • Строка mode: представляет разрешения, которые нужно установить:

    Строка имеет вид [targets][[operator][perms[,perms]], где:

    • targets может содержать любую комбинацию следующих букв:

      • 'u': разрешения применяются к владельцу файла.

      • 'g': разрешения применяются к пользователям из группы файла.

      • 'o': разрешения применяются к другим пользователям, не входящим в группу файла.

      • 'a' (по умолчанию): разрешения применяются ко всем пользователям.

    • operator может быть одной из следующих букв:

      • '+': добавляет разрешения.

      • '-': удаляет разрешения.

      • '=': устанавливает (заменяет) разрешения.

    • perms (можно повторять, разделяя запятыми) может содержать любую комбинацию следующих букв:

      • 'r': чтение.

      • 'w': запись.

      • 'x': выполнение (поиск для каталога).

      • 'X': поиск (только для каталогов; необходимо использовать вместе с '+')

      • 's': UID или GID.

      • 't': бит закрепления.

    Примеры:

    FileUtils.chmod('u=wrx,go=rx', 'src1.txt')
    FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby')
    

Именованные аргументы:

  • noop: true — не изменяет разрешения; возвращает nil.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.chmod(0755, 'src0.txt', noop: true, verbose: true)
    FileUtils.chmod(0644, ['src0.txt', 'src0.dat'], noop: true, verbose: true)
    FileUtils.chmod('u=wrx,go=rx', 'src1.txt', noop: true, verbose: true)
    FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby', noop: true, verbose: true)
    

    Вывод:

    chmod 755 src0.txt
    chmod 644 src0.txt src0.dat
    chmod u=wrx,go=rx src1.txt
    chmod u=wrx,go=rx /usr/bin/ruby

Связанный метод: FileUtils.chmod_R.

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

Как FileUtils.chmod, но рекурсивно изменяет разрешения.

chown (user, group, list, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1894
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; возвращает list, если это массив, и [list] в противном случае:

  • Изменяет каждый элемент, являющийся обычным файлом, с помощью File.chown.

  • Изменяет каждый элемент, являющийся символической ссылкой, с помощью File.lchown.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Пользователь и группа:

  • Аргумент user может быть именем пользователя или идентификатором пользователя; если задано nil или -1, пользователь не изменяется.

  • Аргумент group может быть именем группы или идентификатором группы; если задано nil или -1, группа не изменяется.

  • Пользователь должен входить в группу.

Примеры:

# One path.
# User and group as string names.
File.stat('src0.txt').uid # => 1004
File.stat('src0.txt').gid # => 1004
FileUtils.chown('user2', 'group1', 'src0.txt')
File.stat('src0.txt').uid # => 1006
File.stat('src0.txt').gid # => 1005

# User and group as uid and gid.
FileUtils.chown(1004, 1004, 'src0.txt')
File.stat('src0.txt').uid # => 1004
File.stat('src0.txt').gid # => 1004

# Array of paths.
FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'])

# Directory (not recursive).
FileUtils.chown('user2', 'group1', '.')

Именованные аргументы:

  • noop: true — не изменяет разрешения; возвращает nil.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.chown('user2', 'group1', 'src0.txt', noop: true, verbose: true)
    FileUtils.chown(1004, 1004, 'src0.txt', noop: true, verbose: true)
    FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'], noop: true, verbose: true)
    FileUtils.chown('user2', 'group1', path, noop: true, verbose: true)
    FileUtils.chown('user2', 'group1', '.', noop: true, verbose: true)
    

    Вывод:

    chown user2:group1 src0.txt
    chown 1004:1004 src0.txt
    chown 1006:1005 src0.txt src0.dat
    chown user2:group1 src0.txt
    chown user2:group1 .

Связанный метод: FileUtils.chown_R.

chown_R (user, group, list, noop: nil, verbose: nil, force: nil) Показать исходный код
# File lib/fileutils.rb, line 1910
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

Как FileUtils.chown, но рекурсивно изменяет владельца и группу.

cmp (a, b)
Псевдоним для: compare_file
collect_method (opt) Показать исходный код
# File lib/fileutils.rb, line 2616
def self.collect_method(opt)
  OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }
end

Возвращает массив строковых имен методов, принимающих заданную именованную опцию opt; аргумент должен быть символом:

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

Возвращает массив строковых имен методов FileUtils, принимающих один или несколько именованных аргументов:

FileUtils.commands.sort.take(3) # => ["cd", "chdir", "chmod"]
compare_file (a, b) Показать исходный код
# File lib/fileutils.rb, line 1505
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 идентично, и false в противном случае.

Аргументы a и b должны быть интерпретируемы как путь.

FileUtils.identical? и FileUtils.cmp — псевдонимы FileUtils.compare_file.

Связанный метод: FileUtils.compare_stream.

Также имеет псевдонимы: identical?, cmp
compare_stream (a, b) Показать исходный код
# File lib/fileutils.rb, line 1528
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 идентично, и false в противном случае.

Аргументы a и b должны быть интерпретируемы как путь.

Связанный метод: FileUtils.compare_file.

copy (src, dest, preserve: nil, noop: nil, verbose: nil)
Псевдоним для: cp
copy_entry (src, dest, preserve = false, dereference_root = false, remove_destination = false) Показать исходный код
# File lib/fileutils.rb, line 1037
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
  if dereference_root
    src = File.realpath(src)
  end

  Entry_.new(src, nil, false).wrap_traverse(proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
    ent.copy destent.path
  end, proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    ent.copy_metadata destent.path if preserve
  end)
end

Рекурсивно копирует файлы из src в dest.

Аргументы src и dest должны быть интерпретируемы как пути.

Если src — путь к файлу, копирует src в dest:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.copy_entry('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

Если src — каталог, рекурсивно копирует src в dest:

tree('src1')
# => src1
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.copy_entry('src1', 'dest1')
tree('dest1')
# => dest1
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#        |-- src2.txt
#        `-- src3.txt

При рекурсивном копировании сохраняются типы обычных файлов, каталогов и символических ссылок; другие типы файлов (потоки FIFO, файлы устройств и т. д.) не поддерживаются.

Необязательные аргументы:

  • dereference_root — если src является символической ссылкой, следует по ссылке (по умолчанию — false).

  • preserve — сохраняет время изменения файлов (по умолчанию — false).

  • remove_destination — удаляет dest перед копированием файлов (по умолчанию — false).

Связанные методы: методы копирования.

copy_file (src, dest, preserve = false, dereference = true) Показать исходный код
# File lib/fileutils.rb, line 1073
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 должны быть интерпретируемы как пути.

Примеры:

FileUtils.touch('src0.txt')
FileUtils.copy_file('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true

Необязательные аргументы:

  • dereference — если src является символической ссылкой, следует по ссылке (по умолчанию — true).

  • preserve — сохраняет время изменения файлов (по умолчанию — false).

  • remove_destination — удаляет dest перед копированием файлов (по умолчанию — false).

Связанные методы: методы копирования.

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

Копирует поток ввода-вывода src в поток ввода-вывода dest с помощью IO.copy_stream.

Связанные методы: методы копирования.

cp (src, dest, preserve: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 870
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 (один путь) должны быть интерпретируемы как пути.

Если src — путь к файлу, а dest не является путем к каталогу, копирует src в dest:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

Если src — путь к файлу, а dest — путь к каталогу, копирует src в dest/src:

FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true

Если src — массив путей к файлам, а dest — путь к каталогу, копирует каждый src в dest:

src_file_paths = ['src2.txt', 'src2.dat']
FileUtils.touch(src_file_paths)
FileUtils.mkdir('dest2')
FileUtils.cp(src_file_paths, 'dest2')
File.file?('dest2/src2.txt') # => true
File.file?('dest2/src2.dat') # => true

Именованные аргументы:

  • preserve: true — сохраняет время изменения файлов.

  • noop: true — не копирует файлы.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true)
    FileUtils.cp(src_file_paths, 'dest2', noop: true, verbose: true)
    

    Вывод:

    cp src0.txt dest0.txt
    cp src1.txt dest1
    cp src2.txt src2.dat dest2
    

Вызывает исключение, если src является каталогом.

Связанные методы: методы копирования.

Также имеет псевдоним: copy
cp_lr (src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false) Показать исходный код
# File lib/fileutils.rb, line 628
def cp_lr(src, dest, noop: nil, verbose: nil,
          dereference_root: true, remove_destination: false)
  fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
  return if noop
  fu_each_src_dest(src, dest) do |s, d|
    link_entry s, d, dereference_root, remove_destination
  end
end

Создает жесткие ссылки.

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемы как пути.

Если src — путь к каталогу, а dest не существует, создает ссылки dest и его потомков, указывающие на src и его потомков:

tree('src0')
# => src0
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
File.exist?('dest0') # => false
FileUtils.cp_lr('src0', 'dest0')
tree('dest0')
# => dest0
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt

Если src и dest являются путями к каталогам, создает ссылки dest/src и его потомков, указывающие на src и его потомков:

tree('src1')
# => src1
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.mkdir('dest1')
FileUtils.cp_lr('src1', 'dest1')
tree('dest1')
# => dest1
#    `-- src1
#        |-- sub0
#        |   |-- src0.txt
#        |   `-- src1.txt
#        `-- sub1
#            |-- src2.txt
#            `-- src3.txt

Если src — массив путей к элементам, а dest — путь к каталогу, для каждого пути filepath в src создает ссылку в dest/filepath, указывающую на этот путь:

tree('src2')
# => src2
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.mkdir('dest2')
FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2')
tree('dest2')
# => dest2
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt

Именованные аргументы:

  • dereference_root: false — если src является символической ссылкой, не разыменовывает ее.

  • noop: true — не создает ссылки.

  • remove_destination: true — удаляет dest перед созданием ссылок.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true)
    FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true)
    FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2', noop: true, verbose: true)
    

    Вывод:

    cp -lr src0 dest0
    cp -lr src1 dest1
    cp -lr src2/sub0 src2/sub1 dest2

Вызывает исключение, если dest — путь к существующему файлу или каталогу, а именованный аргумент remove_destination: true не задан.

Связанные методы: методы копирования.

cp_r (src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) Показать исходный код
# File lib/fileutils.rb, line 982
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 (один путь) должны быть интерпретируемы как пути.

Режим доступа, владелец и группа сохраняются при копировании; чтобы изменить их, используйте вместо этого FileUtils.install.

Если src — путь к файлу, а dest не является путем к каталогу, копирует src в dest:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp_r('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

Если src — путь к файлу, а dest — путь к каталогу, копирует src в dest/src:

FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp_r('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true

Если src — путь к каталогу, а dest не существует, рекурсивно копирует src в dest:

tree('src2')
# => src2
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt
FileUtils.exist?('dest2') # => false
FileUtils.cp_r('src2', 'dest2')
tree('dest2')
# => dest2
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt

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

tree('src3')
# => src3
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt
FileUtils.mkdir('dest3')
FileUtils.cp_r('src3', 'dest3')
tree('dest3')
# => dest3
#    `-- src3
#      |-- dir0
#      |   |-- src0.txt
#      |   `-- src1.txt
#      `-- dir1
#          |-- src2.txt
#          `-- src3.txt

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

Именованные аргументы:

  • dereference_root: false — если src является символической ссылкой, не разыменовывает ее.

  • noop: true — не копирует файлы.

  • preserve: true — сохраняет время изменения файлов.

  • remove_destination: true — удаляет dest перед копированием файлов.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true)
    FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true)
    FileUtils.cp_r('src3', 'dest3', noop: true, verbose: true)
    

    Вывод:

    cp -r src0.txt dest0.txt
    cp -r src1.txt dest1
    cp -r src2 dest2
    cp -r src3 dest3

Вызывает исключение, если src — путь к каталогу, а dest — путь к файлу.

Связанные методы: методы копирования.

getwd ()
Псевдоним для: pwd
have_option? (mid, opt) Показать исходный код
# File lib/fileutils.rb, line 2595
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, и false в противном случае; аргументы могут быть строками или символами:

FileUtils.have_option?(:chmod, :noop) # => true
FileUtils.have_option?('chmod', 'secure') # => false
identical? (a, b)
Псевдоним для: compare_file
install (src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1607
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
      if d.end_with?('/')
        mkdir_p d
        copy_file s, d + File.basename(s)
      else
        mkdir_p File.expand_path('..', d)
        copy_file s, d
      end
      File.utime st.atime, st.mtime, d if preserve
      File.chmod fu_mode(mode, st), d if mode
      File.chown uid, gid, d if uid or gid
    end
  end
end

Копирует элемент файла. См. install(1).

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемы как пути;

Если элемент по адресу dest не существует, копирует из src в dest:

File.read('src0.txt')    # => "aaa\n"
File.exist?('dest0.txt') # => false
FileUtils.install('src0.txt', 'dest0.txt')
File.read('dest0.txt')   # => "aaa\n"

Если dest — элемент-файл, копирует из src в dest с перезаписью:

File.read('src1.txt')  # => "aaa\n"
File.read('dest1.txt') # => "bbb\n"
FileUtils.install('src1.txt', 'dest1.txt')
File.read('dest1.txt') # => "aaa\n"

Если dest — элемент-каталог, копирует из src в dest/src, при необходимости перезаписывая:

File.read('src2.txt')       # => "aaa\n"
File.read('dest2/src2.txt') # => "bbb\n"
FileUtils.install('src2.txt', 'dest2')
File.read('dest2/src2.txt') # => "aaa\n"

Если src — массив путей, а dest указывает на каталог, копирует каждый путь path из src в dest/path:

File.file?('src3.txt') # => true
File.file?('src3.dat') # => true
FileUtils.mkdir('dest3')
FileUtils.install(['src3.txt', 'src3.dat'], 'dest3')
File.file?('dest3/src3.txt') # => true
File.file?('dest3/src3.dat') # => true

Именованные аргументы:

  • group: group — изменяет группу, если значение не равно nil, с помощью File.chown.

  • mode: permissions — изменяет разрешения с помощью File.chmod.

  • noop: true — не копирует элементы; возвращает nil.

  • owner: owner — изменяет владельца, если значение не равно nil, с помощью File.chown.

  • preserve: true — сохраняет временные метки с помощью File.utime.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true)
    FileUtils.install('src2.txt', 'dest2', noop: true, verbose: true)
    

    Вывод:

    install -c src0.txt dest0.txt
    install -c src1.txt dest1.txt
    install -c src2.txt dest2

Связанные методы: методы копирования.

link (src, dest, force: nil, noop: nil, verbose: nil)
Псевдоним для: ln
link_entry (src, dest, dereference_root = false, remove_destination = false) Показать исходный код
# File lib/fileutils.rb, line 809
def link_entry(src, dest, dereference_root = false, remove_destination = false)
  Entry_.new(src, nil, dereference_root).traverse do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    File.unlink destent.path if remove_destination && File.file?(destent.path)
    ent.link destent.path
  end
end

Создает жесткие ссылки; возвращает nil.

Аргументы src и dest должны быть интерпретируемы как пути.

Если src — путь к файлу, а dest не существует, создает жесткую ссылку в dest, указывающую на src:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.link_entry('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

Если src — путь к каталогу, а dest не существует, рекурсивно создает жесткие ссылки в dest, указывающие на пути в src:

FileUtils.mkdir_p(['src1/dir0', 'src1/dir1'])
src_file_paths = [
  'src1/dir0/t0.txt',
  'src1/dir0/t1.txt',
  'src1/dir1/t2.txt',
  'src1/dir1/t3.txt',
  ]
FileUtils.touch(src_file_paths)
File.directory?('dest1')        # => true
FileUtils.link_entry('src1', 'dest1')
File.file?('dest1/dir0/t0.txt') # => true
File.file?('dest1/dir0/t1.txt') # => true
File.file?('dest1/dir1/t2.txt') # => true
File.file?('dest1/dir1/t3.txt') # => true

Необязательные аргументы:

  • dereference_root — разыменовывает src, если это символическая ссылка (по умолчанию — false).

  • remove_destination — удаляет dest перед созданием ссылок (по умолчанию — false).

Вызывает исключение, если dest — путь к существующему файлу или каталогу, а необязательный аргумент remove_destination не задан.

Связанный метод: FileUtils.ln (имеет другие параметры).

ln (src, dest, force: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 517
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

Создаёт жёсткие ссылки.

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемыми как пути.

Если src — путь к существующему файлу, а dest — путь к несуществующему файлу, создаёт жёсткую ссылку в dest, указывающую на src; возвращает ноль:

Dir.children('tmp0/')                    # => ["t.txt"]
Dir.children('tmp1/')                    # => []
FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk') # => 0
Dir.children('tmp1/')                    # => ["t.lnk"]

Если src — путь к существующему файлу, а dest — путь к существующему каталогу, создаёт жёсткую ссылку в dest/src, указывающую на src; возвращает ноль:

Dir.children('tmp2')               # => ["t.dat"]
Dir.children('tmp3')               # => []
FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0
Dir.children('tmp3')               # => ["t.dat"]

Если src — массив путей к существующим файлам, а dest — путь к существующему каталогу, то для каждого пути target из src создаёт жёсткую ссылку в dest/target, указывающую на target; возвращает src:

Dir.children('tmp4/')                               # => []
FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/') # => ["tmp0/t.txt", "tmp2/t.dat"]
Dir.children('tmp4/')                               # => ["t.dat", "t.txt"]

Именованные аргументы:

  • force: true — перезаписывает dest, если он существует.

  • noop: true — не создаёт ссылки.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true)
    FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true)
    FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/', verbose: true)
    

    Вывод:

    ln tmp0/t.txt tmp1/t.lnk
    ln tmp2/t.dat tmp3
    ln tmp0/t.txt tmp2/t.dat tmp4/

Вызывает исключение, если dest — путь к существующему файлу, а именованный аргумент force не равен true.

Связанный метод: FileUtils.link_entry (имеет другие параметры).

Также имеет псевдоним: link
ln_s (src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 707
def ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
  if relative
    return ln_sr(src, dest, force: force, target_directory: target_directory, noop: noop, verbose: verbose)
  end
  fu_output_message "ln -s#{force ? 'f' : ''}#{
    target_directory ? '' : 'T'} #{[src,dest].flatten.join ' '}" if verbose
  return if noop
  fu_each_src_dest0(src, dest, target_directory) do |s,d|
    remove_file d, true if force
    File.symlink s, d
  end
end

Создаёт символические ссылки.

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемыми как пути.

Если src — путь к существующему файлу:

  • Если dest — путь к несуществующему файлу, создаёт символическую ссылку в dest, указывающую на src:

    FileUtils.touch('src0.txt')
    File.exist?('dest0.txt')   # => false
    FileUtils.ln_s('src0.txt', 'dest0.txt')
    File.symlink?('dest0.txt') # => true
    
  • Если dest — путь к существующему файлу, создаёт символическую ссылку в dest, указывающую на src, только если задан именованный аргумент force: true (в противном случае вызывает исключение):

    FileUtils.touch('src1.txt')
    FileUtils.touch('dest1.txt')
    FileUtils.ln_s('src1.txt', 'dest1.txt', force: true)
    FileTest.symlink?('dest1.txt') # => true
    
    FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
    

Если dest — путь к каталогу, создаёт символическую ссылку в dest/src, указывающую на src:

FileUtils.touch('src2.txt')
FileUtils.mkdir('destdir2')
FileUtils.ln_s('src2.txt', 'destdir2')
File.symlink?('destdir2/src2.txt') # => true

Если src — массив путей к существующим файлам, а dest — каталог, то для каждого дочернего элемента child в src создаёт символическую ссылку dest/child, указывающую на child:

FileUtils.mkdir('srcdir3')
FileUtils.touch('srcdir3/src0.txt')
FileUtils.touch('srcdir3/src1.txt')
FileUtils.mkdir('destdir3')
FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3')
File.symlink?('destdir3/src0.txt') # => true
File.symlink?('destdir3/src1.txt') # => true

Именованные аргументы:

  • force: true — перезаписывает dest, если он существует.

  • relative: false — создаёт ссылки относительно dest.

  • noop: true — не создаёт ссылки.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true)
    FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true)
    FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3', noop: true, verbose: true)
    

    Вывод:

    ln -s src0.txt dest0.txt
    ln -s src1.txt destdir1
    ln -sf src2.txt dest2.txt
    ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3

Связанный метод: FileUtils.ln_sf.

Также имеет псевдоним: symlink
ln_sf (src, dest, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 726
def ln_sf(src, dest, noop: nil, verbose: nil)
  ln_s src, dest, force: true, noop: noop, verbose: verbose
end

Аналогично FileUtils.ln_s, но именованный аргумент force: true всегда задан.

ln_sr (src, dest, target_directory: true, force: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 733
def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
  cmd = "ln -s#{force ? 'f' : ''}#{target_directory ? '' : 'T'}" if verbose
  fu_each_src_dest0(src, dest, target_directory) do |s,d|
    if target_directory
      parent = File.dirname(d)
      destdirs = fu_split_path(parent)
      real_ddirs = fu_split_path(File.realpath(parent))
    else
      destdirs ||= fu_split_path(dest)
      real_ddirs ||= fu_split_path(File.realdirpath(dest))
    end
    srcdirs = fu_split_path(s)
    i = fu_common_components(srcdirs, destdirs)
    n = destdirs.size - i
    n -= 1 unless target_directory
    link1 = fu_clean_components(*Array.new([n, 0].max, '..'), *srcdirs[i..-1])
    begin
      real_sdirs = fu_split_path(File.realdirpath(s)) rescue nil
    rescue
    else
      i = fu_common_components(real_sdirs, real_ddirs)
      n = real_ddirs.size - i
      n -= 1 unless target_directory
      link2 = fu_clean_components(*Array.new([n, 0].max, '..'), *real_sdirs[i..-1])
      link1 = link2 if link1.size > link2.size
    end
    s = File.join(link1)
    fu_output_message [cmd, s, d].flatten.join(' ') if verbose
    next if noop
    remove_file d, true if force
    File.symlink s, d
  end
end

Аналогично FileUtils.ln_s, но создаёт ссылки относительно dest.

makedirs (list, mode: nil, noop: nil, verbose: nil)
Псевдоним для: mkdir_p
mkdir (list, mode: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 317
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

Создаёт каталоги по путям из указанного list (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемыми как пути.

Если именованные аргументы не указаны, создаёт каталог для каждого path в list, вызывая Dir.mkdir(path, mode); см. Dir.mkdir:

FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"]
FileUtils.mkdir('tmp4')        # => ["tmp4"]

Именованные аргументы:

  • mode: mode — также вызывает File.chmod(mode, path); см. File.chmod.

  • noop: true — не создаёт каталоги.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.mkdir(%w[tmp0 tmp1], verbose: true)
    FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
    

    Вывод:

    mkdir tmp0 tmp1
    mkdir -m 700 tmp2 tmp3

Вызывает исключение, если какой-либо путь указывает на существующий файл или каталог либо если по какой-либо причине каталог не удаётся создать.

Связанный метод: FileUtils.mkdir_p.

mkdir_p (list, mode: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 366
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.each do |item|
    path = remove_trailing_slash(item)

    stack = []
    until File.directory?(path) || File.dirname(path) == path
      stack.push path
      path = File.dirname(path)
    end
    stack.reverse_each do |dir|
      begin
        fu_mkdir dir, mode
      rescue SystemCallError
        raise unless File.directory?(dir)
      end
    end
  end

  return *list
end

Создаёт каталоги по путям из указанного list (один путь или массив путей), при необходимости также создавая родительские каталоги; возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемыми как пути.

Если именованные аргументы не указаны, создаёт каталог для каждого path в list, а также все необходимые родительские каталоги, вызывая Dir.mkdir(path, mode); см. Dir.mkdir:

FileUtils.mkdir_p(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
FileUtils.mkdir_p('tmp4/tmp5')             # => ["tmp4/tmp5"]

Именованные аргументы:

  • mode: mode — также вызывает File.chmod(mode, path); см. File.chmod.

  • noop: true — не создаёт каталоги.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.mkdir_p(%w[tmp0 tmp1], verbose: true)
    FileUtils.mkdir_p(%w[tmp2 tmp3], mode: 0700, verbose: true)
    

    Вывод:

    mkdir -p tmp0 tmp1
    mkdir -p -m 700 tmp2 tmp3

Вызывает исключение, если по какой-либо причине каталог не удаётся создать.

FileUtils.mkpath и FileUtils.makedirs являются псевдонимами для FileUtils.mkdir_p.

Связанный метод: FileUtils.mkdir.

Также имеет псевдонимы: 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/fileutils.rb, line 1154
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
        end
      end
      begin
        File.rename s, d
      rescue Errno::EXDEV,
             Errno::EPERM # move from unencrypted to encrypted dir (ext4)
        copy_entry s, d, true
        if secure
          remove_entry_secure s, force
        else
          remove_entry s, force
        end
      end
    rescue SystemCallError
      raise unless force
    end
  end
end

Перемещает элементы.

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемыми как пути.

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

Может привести к локальной уязвимости, если вызван без именованного аргумента secure: true; см. Как избежать уязвимости TOCTTOU.

Если src — путь к одному файлу или каталогу, а dest не существует, перемещает src в dest:

tree('src0')
# => src0
#    |-- src0.txt
#    `-- src1.txt
File.exist?('dest0') # => false
FileUtils.mv('src0', 'dest0')
File.exist?('src0')  # => false
tree('dest0')
# => dest0
#    |-- src0.txt
#    `-- src1.txt

Если src — массив путей к файлам и каталогам, а dest — путь к каталогу, копирует каждый путь из массива в dest:

File.file?('src1.txt') # => true
tree('src1')
# => src1
#    |-- src.dat
#    `-- src.txt
Dir.empty?('dest1')    # => true
FileUtils.mv(['src1.txt', 'src1'], 'dest1')
tree('dest1')
# => dest1
#    |-- src1
#    |   |-- src.dat
#    |   `-- src.txt
#    `-- src1.txt

Именованные аргументы:

  • force: true — если перемещение включает удаление src (то есть если src и dest находятся в разных файловых системах), игнорирует возникающие исключения класса StandardError и его подклассов.

  • noop: true — не перемещает файлы.

  • secure: true — безопасно удаляет src; подробности см. в FileUtils.remove_entry_secure.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.mv('src0', 'dest0', noop: true, verbose: true)
    FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
    

    Вывод:

    mv src0 dest0
    mv src1.txt src1 dest1
    
Также имеет псевдоним: move
options () Показать исходный код
# File lib/fileutils.rb, line 2585
def self.options
  OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
end

Возвращает массив строковых имён именованных аргументов:

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

Возвращает массив строковых имён именованных аргументов метода mid; аргумент может быть строкой или символом:

FileUtils.options_of(:rm) # => ["force", "noop", "verbose"]
FileUtils.options_of('mv') # => ["force", "noop", "verbose", "secure"]
pwd () Показать исходный код
# File lib/fileutils.rb, line 198
def pwd
  Dir.pwd
end

Возвращает строку, содержащую путь к текущему каталогу:

FileUtils.pwd # => "/rdoc/fileutils"

Связанный метод: FileUtils.cd.

Также имеет псевдоним: getwd
remove (list, force: nil, noop: nil, verbose: nil)
Псевдоним для: rm
remove_dir (path, force = false) Показать исходный код
# File lib/fileutils.rb, line 1489
def remove_dir(path, force = false)
  raise Errno::ENOTDIR, path unless force or File.directory?(path)
  remove_entry path, force
end

Рекурсивно удаляет элемент каталога, заданный аргументом path, который должен обозначать обычный файл, символическую ссылку или каталог.

Аргумент path должен быть интерпретируемым как путь.

Необязательный аргумент force указывает, следует ли игнорировать возникающие исключения класса StandardError и его подклассов.

Связанные методы: методы удаления.

remove_entry (path, force = false) Показать исходный код
# File lib/fileutils.rb, line 1446
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 должен быть интерпретируемым как путь.

Необязательный аргумент force указывает, следует ли игнорировать возникающие исключения класса StandardError и его подклассов.

Связанный метод: FileUtils.remove_entry_secure.

remove_entry_secure (path, force = false) Показать исходный код
# File lib/fileutils.rb, line 1348
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
  dot_file = fullpath + "/."
  begin
    File.open(dot_file) {|f|
      unless fu_stat_identical_entry?(st, f.stat)
        # symlink (TOC-to-TOU attack?)
        File.unlink fullpath
        return
      end
      f.chown euid, -1
      f.chmod 0700
    }
  rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
    File.lstat(dot_file).tap {|fstat|
      unless fu_stat_identical_entry?(st, fstat)
        # symlink (TOC-to-TOU attack?)
        File.unlink fullpath
        return
      end
      File.chown euid, -1, dot_file
      File.chmod 0700, dot_file
    }
  end

  unless fu_stat_identical_entry?(st, File.lstat(fullpath))
    # TOC-to-TOU attack?
    File.unlink fullpath
    return
  end

  # ---- tree root is frozen ----
  root = Entry_.new(path)
  root.preorder_traverse do |ent|
    if ent.directory?
      ent.chown euid, -1
      ent.chmod 0700
    end
  end
  root.postorder_traverse do |ent|
    begin
      ent.remove
    rescue
      raise unless force
    end
  end
rescue
  raise unless force
end

Безопасно удаляет элемент, заданный аргументом path, который должен обозначать обычный файл, символическую ссылку или каталог.

Аргумент path должен быть интерпретируемым как путь.

Предотвращает локальную уязвимость, которая может возникать при определённых обстоятельствах; см. Как избежать уязвимости TOCTTOU.

Необязательный аргумент force указывает, следует ли игнорировать возникающие исключения класса StandardError и его подклассов.

Связанные методы: методы удаления.

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

Удаляет файловый элемент, заданный аргументом path, который должен обозначать обычный файл или символическую ссылку.

Аргумент path должен быть интерпретируемым как путь.

Необязательный аргумент force указывает, следует ли игнорировать возникающие исключения класса StandardError и его подклассов.

Связанные методы: методы удаления.

rm (list, force: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1213
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 (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемыми как пути.

Если именованные аргументы не указаны, удаляет файлы по путям, заданным в list:

FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]

Именованные аргументы:

  • force: true — игнорирует возникающие исключения класса StandardError и его подклассов.

  • noop: true — не удаляет файлы; возвращает nil.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
    

    Вывод:

    rm src0.dat src0.txt
    

Связанные методы: методы удаления.

Также имеет псевдоним: remove
rm_f (list, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1238
def rm_f(list, noop: nil, verbose: nil)
  rm list, force: true, noop: noop, verbose: verbose
end

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

FileUtils.rm(list, force: true, **kwargs)

Аргумент list (один путь или массив путей) должен быть интерпретируемым как путь.

Список именованных аргументов см. в FileUtils.rm.

Связанные методы: методы удаления.

Также имеет псевдоним: safe_unlink
rm_r (list, force: nil, noop: nil, verbose: nil, secure: nil) Показать исходный код
# File lib/fileutils.rb, line 1296
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 (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемыми как пути.

Может привести к локальной уязвимости, если вызван без именованного аргумента secure: true; см. Как избежать уязвимости TOCTTOU.

Для каждого пути к файлу удаляет файл по этому пути:

FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm_r(['src0.dat', 'src0.txt'])
File.exist?('src0.txt') # => false
File.exist?('src0.dat') # => false

Для каждого пути к каталогу рекурсивно удаляет файлы и каталоги:

tree('src1')
# => src1
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.rm_r('src1')
File.exist?('src1') # => false

Именованные аргументы:

  • force: true — игнорирует возникающие исключения класса StandardError и его подклассов.

  • noop: true — не удаляет элементы; возвращает nil.

  • secure: true — безопасно удаляет src; подробности см. в FileUtils.remove_entry_secure.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true)
    FileUtils.rm_r('src1', noop: true, verbose: true)
    

    Вывод:

    rm -r src0.dat src0.txt
    rm -r src1

Связанные методы: методы удаления.

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

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

FileUtils.rm_r(list, force: true, **kwargs)

Аргумент list или его элементы должны быть интерпретируемыми как пути.

Может привести к локальной уязвимости, если вызван без именованного аргумента secure: true; см. Как избежать уязвимости TOCTTOU.

Список именованных аргументов см. в FileUtils.rm_r.

Связанные методы: методы удаления.

Также имеет псевдоним: rmtree
rmdir (list, parents: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 443
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|
    Dir.rmdir(dir = remove_trailing_slash(dir))
    if parents
      begin
        until (parent = File.dirname(dir)) == '.' or parent == dir
          dir = parent
          Dir.rmdir(dir)
        end
      rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
      end
    end
  end
end

Удаляет каталоги по путям из указанного list (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемыми как пути.

Если именованные аргументы не указаны, удаляет каталог для каждого path в list, вызывая Dir.rmdir(path); см. Dir.rmdir:

FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
FileUtils.rmdir('tmp4/tmp5')             # => ["tmp4/tmp5"]

Именованные аргументы:

  • parents: true — удаляет следующие друг за другом родительские каталоги, если они пусты.

  • noop: true — не удаляет каталоги.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true)
    FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
    

    Вывод:

    rmdir -p tmp0/tmp1 tmp2/tmp3
    rmdir -p tmp4/tmp5

Вызывает исключение, если каталог не существует или если по какой-либо причине его не удаётся удалить.

Связанные методы: методы удаления.

rmtree (list, noop: nil, verbose: nil, secure: nil)
Псевдоним для: rm_rf
safe_unlink (list, noop: nil, verbose: nil)
Псевдоним для: rm_f
symlink (src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
Псевдоним для: ln_s
touch (list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) Показать исходный код
# File lib/fileutils.rb, line 2004
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 (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

По умолчанию создаёт пустой файл, если путь указывает на несуществующий элемент; чтобы вместо этого вызвать исключение, используйте именованный аргумент nocreate.

Аргумент list или его элементы должны быть интерпретируемыми как пути.

Примеры:

# Single path.
f = File.new('src0.txt') # Existing file.
f.atime # => 2022-06-10 11:11:21.200277 -0700
f.mtime # => 2022-06-10 11:11:21.200277 -0700
FileUtils.touch('src0.txt')
f = File.new('src0.txt')
f.atime # => 2022-06-11 08:28:09.8185343 -0700
f.mtime # => 2022-06-11 08:28:09.8185343 -0700

# Array of paths.
FileUtils.touch(['src0.txt', 'src0.dat'])

Именованные аргументы:

  • mtime: time — устанавливает mtime элемента в указанное время вместо текущего.

  • nocreate: true — вызывает исключение, если элемент не существует.

  • noop: true — не изменяет временные метки элементов; возвращает nil.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.touch('src0.txt', noop: true, verbose: true)
    FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true)
    FileUtils.touch(path, noop: true, verbose: true)
    

    Вывод:

    touch src0.txt
    touch src0.txt src0.dat
    touch src0.txt
    

Связанный метод: FileUtils.uptodate?.

uptodate? (new, old_list) Показать исходный код
# File lib/fileutils.rb, line 265
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; в противном случае — false.

Аргумент new и элементы old_list должны быть интерпретируемы как пути:

FileUtils.uptodate?('Rakefile', ['Gemfile', 'README.md']) # => true
FileUtils.uptodate?('Gemfile', ['Rakefile', 'README.md']) # => false

Несуществующий файл считается бесконечно старым.

Связанный метод: FileUtils.touch.

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

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

Изменяет рабочий каталог на заданный dir, который должен быть интерпретируем как путь:

Если блок не задан, изменяет текущий каталог на каталог по адресу dir; возвращает ноль:

FileUtils.pwd # => "/rdoc/fileutils"
FileUtils.cd('..')
FileUtils.pwd # => "/rdoc"
FileUtils.cd('fileutils')

Если задан блок, изменяет текущий каталог на каталог по адресу dir, вызывает блок с аргументом dir и восстанавливает исходный текущий каталог; возвращает значение блока:

FileUtils.pwd                                     # => "/rdoc/fileutils"
FileUtils.cd('..') { |arg| [arg, FileUtils.pwd] } # => ["..", "/rdoc"]
FileUtils.pwd                                     # => "/rdoc/fileutils"

Именованные аргументы:

  • verbose: true — выводит эквивалентную команду:

    FileUtils.cd('..')
    FileUtils.cd('fileutils')
    

    Вывод:

    cd ..
    cd fileutils

Связанный метод: FileUtils.pwd.

Также имеет псевдоним: chdir
chdir (dir, verbose: nil)
Псевдоним для: cd
chmod (mode, list, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1801
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; возвращает list, если это массив, и [list] в противном случае:

  • Изменяет каждый элемент, являющийся обычным файлом, с помощью File.chmod.

  • Изменяет каждый элемент, являющийся символической ссылкой, с помощью File.lchmod.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Аргумент mode может быть целым числом или строкой:

  • Целое число mode: представляет устанавливаемые биты прав доступа:

    FileUtils.chmod(0755, 'src0.txt')
    FileUtils.chmod(0644, ['src0.txt', 'src0.dat'])
    
  • Строка mode: представляет устанавливаемые права доступа:

    Строка имеет формат [targets][[operator][perms[,perms]], где:

    • targets может содержать любую комбинацию следующих букв:

      • 'u': права доступа применяются к владельцу файла.

      • 'g': права доступа применяются к пользователям из группы файла.

      • 'o': права доступа применяются к другим пользователям, не входящим в группу файла.

      • 'a' (по умолчанию): права доступа применяются ко всем пользователям.

    • operator может быть одной из следующих букв:

      • '+': добавляет права доступа.

      • '-': удаляет права доступа.

      • '=': устанавливает (заменяет) права доступа.

    • perms (может повторяться; элементы разделяются запятыми) может содержать любую комбинацию следующих букв:

      • 'r': чтение.

      • 'w': запись.

      • 'x': выполнение (поиск для каталога).

      • 'X': поиск (только для каталогов; необходимо использовать с '+')

      • 's': uid или gid.

      • 't': бит sticky.

    Примеры:

    FileUtils.chmod('u=wrx,go=rx', 'src1.txt')
    FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby')
    

Именованные аргументы:

  • noop: true — не изменяет права доступа; возвращает nil.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.chmod(0755, 'src0.txt', noop: true, verbose: true)
    FileUtils.chmod(0644, ['src0.txt', 'src0.dat'], noop: true, verbose: true)
    FileUtils.chmod('u=wrx,go=rx', 'src1.txt', noop: true, verbose: true)
    FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby', noop: true, verbose: true)
    

    Вывод:

    chmod 755 src0.txt
    chmod 644 src0.txt src0.dat
    chmod u=wrx,go=rx src1.txt
    chmod u=wrx,go=rx /usr/bin/ruby

Связанный метод: FileUtils.chmod_R.

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

Подобно FileUtils.chmod, но рекурсивно изменяет права доступа.

chown (user, group, list, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1894
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; возвращает list, если это массив, и [list] в противном случае:

  • Изменяет каждый элемент, являющийся обычным файлом, с помощью File.chown.

  • Изменяет каждый элемент, являющийся символической ссылкой, с помощью File.lchown.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Пользователь и группа:

  • Аргумент user может быть именем пользователя или его идентификатором; если задано nil или -1, пользователь не изменяется.

  • Аргумент group может быть именем группы или её идентификатором; если задано nil или -1, группа не изменяется.

  • Пользователь должен входить в группу.

Примеры:

# One path.
# User and group as string names.
File.stat('src0.txt').uid # => 1004
File.stat('src0.txt').gid # => 1004
FileUtils.chown('user2', 'group1', 'src0.txt')
File.stat('src0.txt').uid # => 1006
File.stat('src0.txt').gid # => 1005

# User and group as uid and gid.
FileUtils.chown(1004, 1004, 'src0.txt')
File.stat('src0.txt').uid # => 1004
File.stat('src0.txt').gid # => 1004

# Array of paths.
FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'])

# Directory (not recursive).
FileUtils.chown('user2', 'group1', '.')

Именованные аргументы:

  • noop: true — не изменяет права доступа; возвращает nil.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.chown('user2', 'group1', 'src0.txt', noop: true, verbose: true)
    FileUtils.chown(1004, 1004, 'src0.txt', noop: true, verbose: true)
    FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'], noop: true, verbose: true)
    FileUtils.chown('user2', 'group1', path, noop: true, verbose: true)
    FileUtils.chown('user2', 'group1', '.', noop: true, verbose: true)
    

    Вывод:

    chown user2:group1 src0.txt
    chown 1004:1004 src0.txt
    chown 1006:1005 src0.txt src0.dat
    chown user2:group1 src0.txt
    chown user2:group1 .

Связанный метод: FileUtils.chown_R.

chown_R (user, group, list, noop: nil, verbose: nil, force: nil) Показать исходный код
# File lib/fileutils.rb, line 1910
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

Подобно FileUtils.chown, но рекурсивно изменяет владельца и группу.

cmp (a, b)
Псевдоним для: compare_file
compare_file (a, b) Показать исходный код
# File lib/fileutils.rb, line 1505
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 идентично, и false в противном случае.

Аргументы a и b должны быть интерпретируемы как пути.

FileUtils.identical? и FileUtils.cmp — псевдонимы FileUtils.compare_file.

Связанный метод: FileUtils.compare_stream.

Также имеет псевдонимы: identical?, cmp
compare_stream (a, b) Показать исходный код
# File lib/fileutils.rb, line 1528
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 идентично, и false в противном случае.

Аргументы a и b должны быть интерпретируемы как пути.

Связанный метод: FileUtils.compare_file.

copy (src, dest, preserve: nil, noop: nil, verbose: nil)
Псевдоним для: cp
copy_entry (src, dest, preserve = false, dereference_root = false, remove_destination = false) Показать исходный код
# File lib/fileutils.rb, line 1037
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
  if dereference_root
    src = File.realpath(src)
  end

  Entry_.new(src, nil, false).wrap_traverse(proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
    ent.copy destent.path
  end, proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    ent.copy_metadata destent.path if preserve
  end)
end

Рекурсивно копирует файлы из src в dest.

Аргументы src и dest должны быть интерпретируемы как пути.

Если src — путь к файлу, копирует src в dest:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.copy_entry('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

Если src — каталог, рекурсивно копирует src в dest:

tree('src1')
# => src1
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.copy_entry('src1', 'dest1')
tree('dest1')
# => dest1
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#        |-- src2.txt
#        `-- src3.txt

При рекурсивном копировании сохраняются типы файлов для обычных файлов, каталогов и символических ссылок; другие типы файлов (потоки FIFO, файлы устройств и т. д.) не поддерживаются.

Необязательные аргументы:

  • dereference_root — если src является символической ссылкой, следует по ней (по умолчанию false).

  • preserve — сохраняет время файлов (по умолчанию false).

  • remove_destination — удаляет dest перед копированием файлов (по умолчанию false).

Связанные методы: методы копирования.

copy_file (src, dest, preserve = false, dereference = true) Показать исходный код
# File lib/fileutils.rb, line 1073
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 должны быть интерпретируемы как пути.

Примеры:

FileUtils.touch('src0.txt')
FileUtils.copy_file('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true

Необязательные аргументы:

  • dereference — если src является символической ссылкой, следует по ней (по умолчанию true).

  • preserve — сохраняет время файлов (по умолчанию false).

  • remove_destination — удаляет dest перед копированием файлов (по умолчанию false).

Связанные методы: методы копирования.

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

Копирует поток ввода-вывода src в поток ввода-вывода dest с помощью IO.copy_stream.

Связанные методы: методы копирования.

cp (src, dest, preserve: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 870
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 (один путь) должны быть интерпретируемы как пути.

Если src — путь к файлу, а dest не является путём к каталогу, копирует src в dest:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

Если src — путь к файлу, а dest — путь к каталогу, копирует src в dest/src:

FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true

Если src — массив путей к файлам, а dest — путь к каталогу, копирует каждый src в dest:

src_file_paths = ['src2.txt', 'src2.dat']
FileUtils.touch(src_file_paths)
FileUtils.mkdir('dest2')
FileUtils.cp(src_file_paths, 'dest2')
File.file?('dest2/src2.txt') # => true
File.file?('dest2/src2.dat') # => true

Именованные аргументы:

  • preserve: true — сохраняет время файлов.

  • noop: true — не копирует файлы.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true)
    FileUtils.cp(src_file_paths, 'dest2', noop: true, verbose: true)
    

    Вывод:

    cp src0.txt dest0.txt
    cp src1.txt dest1
    cp src2.txt src2.dat dest2
    

Вызывает исключение, если src является каталогом.

Связанные методы: методы копирования.

Также имеет псевдоним: copy
cp_lr (src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false) Показать исходный код
# File lib/fileutils.rb, line 628
def cp_lr(src, dest, noop: nil, verbose: nil,
          dereference_root: true, remove_destination: false)
  fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
  return if noop
  fu_each_src_dest(src, dest) do |s, d|
    link_entry s, d, dereference_root, remove_destination
  end
end

Создаёт жёсткие ссылки.

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемы как пути.

Если src — путь к каталогу, а dest не существует, создаёт ссылки dest и его потомков, указывающие на src и его потомков:

tree('src0')
# => src0
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
File.exist?('dest0') # => false
FileUtils.cp_lr('src0', 'dest0')
tree('dest0')
# => dest0
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt

Если src и dest — пути к каталогам, создаёт ссылки dest/src и его потомков, указывающие на src и его потомков:

tree('src1')
# => src1
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.mkdir('dest1')
FileUtils.cp_lr('src1', 'dest1')
tree('dest1')
# => dest1
#    `-- src1
#        |-- sub0
#        |   |-- src0.txt
#        |   `-- src1.txt
#        `-- sub1
#            |-- src2.txt
#            `-- src3.txt

Если src — массив путей к элементам, а dest — путь к каталогу, для каждого пути filepath из src создаёт ссылку по адресу dest/filepath, указывающую на этот путь:

tree('src2')
# => src2
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.mkdir('dest2')
FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2')
tree('dest2')
# => dest2
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt

Именованные аргументы:

  • dereference_root: false — если src является символической ссылкой, не переходит по ней.

  • noop: true — не создаёт ссылки.

  • remove_destination: true — удаляет dest перед созданием ссылок.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true)
    FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true)
    FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2', noop: true, verbose: true)
    

    Вывод:

    cp -lr src0 dest0
    cp -lr src1 dest1
    cp -lr src2/sub0 src2/sub1 dest2

Вызывает исключение, если dest — путь к существующему файлу или каталогу и не задан именованный аргумент remove_destination: true.

Связанные методы: методы копирования.

cp_r (src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) Показать исходный код
# File lib/fileutils.rb, line 982
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 (один путь) должны быть интерпретируемы как пути.

Режим доступа, владелец и группа сохраняются в копии; чтобы изменить их, используйте вместо этого FileUtils.install.

Если src — путь к файлу, а dest не является путём к каталогу, копирует src в dest:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp_r('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

Если src — путь к файлу, а dest — путь к каталогу, копирует src в dest/src:

FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp_r('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true

Если src — путь к каталогу, а dest не существует, рекурсивно копирует src в dest:

tree('src2')
# => src2
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt
FileUtils.exist?('dest2') # => false
FileUtils.cp_r('src2', 'dest2')
tree('dest2')
# => dest2
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt

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

tree('src3')
# => src3
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt
FileUtils.mkdir('dest3')
FileUtils.cp_r('src3', 'dest3')
tree('dest3')
# => dest3
#    `-- src3
#      |-- dir0
#      |   |-- src0.txt
#      |   `-- src1.txt
#      `-- dir1
#          |-- src2.txt
#          `-- src3.txt

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

Именованные аргументы:

  • dereference_root: false — если src является символической ссылкой, не переходит по ней.

  • noop: true — не копирует файлы.

  • preserve: true — сохраняет время файлов.

  • remove_destination: true — удаляет dest перед копированием файлов.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true)
    FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true)
    FileUtils.cp_r('src3', 'dest3', noop: true, verbose: true)
    

    Вывод:

    cp -r src0.txt dest0.txt
    cp -r src1.txt dest1
    cp -r src2 dest2
    cp -r src3 dest3

Вызывает исключение, если src — путь к каталогу, а dest — путь к файлу.

Связанные методы: методы копирования.

getwd ()
Псевдоним для: pwd
identical? (a, b)
Псевдоним для: compare_file
install (src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1607
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
      if d.end_with?('/')
        mkdir_p d
        copy_file s, d + File.basename(s)
      else
        mkdir_p File.expand_path('..', d)
        copy_file s, d
      end
      File.utime st.atime, st.mtime, d if preserve
      File.chmod fu_mode(mode, st), d if mode
      File.chown uid, gid, d if uid or gid
    end
  end
end

Копирует элемент файла. См. install(1).

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемы как пути;

Если элемент по адресу dest не существует, копирует из src в dest:

File.read('src0.txt')    # => "aaa\n"
File.exist?('dest0.txt') # => false
FileUtils.install('src0.txt', 'dest0.txt')
File.read('dest0.txt')   # => "aaa\n"

Если dest — элемент-файл, копирует из src в dest, перезаписывая его:

File.read('src1.txt')  # => "aaa\n"
File.read('dest1.txt') # => "bbb\n"
FileUtils.install('src1.txt', 'dest1.txt')
File.read('dest1.txt') # => "aaa\n"

Если dest — элемент-каталог, копирует из src в dest/src, при необходимости перезаписывая его:

File.read('src2.txt')       # => "aaa\n"
File.read('dest2/src2.txt') # => "bbb\n"
FileUtils.install('src2.txt', 'dest2')
File.read('dest2/src2.txt') # => "aaa\n"

Если src — массив путей, а dest указывает на каталог, копирует каждый путь path из src в dest/path:

File.file?('src3.txt') # => true
File.file?('src3.dat') # => true
FileUtils.mkdir('dest3')
FileUtils.install(['src3.txt', 'src3.dat'], 'dest3')
File.file?('dest3/src3.txt') # => true
File.file?('dest3/src3.dat') # => true

Именованные аргументы:

  • group: group — изменяет группу, если значение не равно nil, используя File.chown.

  • mode: permissions — изменяет права доступа, используя File.chmod.

  • noop: true — не копирует элементы; возвращает nil.

  • owner: owner — изменяет владельца, если значение не равно nil, используя File.chown.

  • preserve: true — сохраняет метки времени с помощью File.utime.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true)
    FileUtils.install('src2.txt', 'dest2', noop: true, verbose: true)
    

    Вывод:

    install -c src0.txt dest0.txt
    install -c src1.txt dest1.txt
    install -c src2.txt dest2

Связанные методы: методы копирования.

link (src, dest, force: nil, noop: nil, verbose: nil)
Псевдоним для: ln
link_entry (src, dest, dereference_root = false, remove_destination = false) Показать исходный код
# File lib/fileutils.rb, line 809
def link_entry(src, dest, dereference_root = false, remove_destination = false)
  Entry_.new(src, nil, dereference_root).traverse do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    File.unlink destent.path if remove_destination && File.file?(destent.path)
    ent.link destent.path
  end
end

Создаёт жёсткие ссылки; возвращает nil.

Аргументы src и dest должны быть интерпретируемы как пути.

Если src — путь к файлу, а dest не существует, создаёт жёсткую ссылку по адресу dest, указывающую на src:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.link_entry('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

Если src — путь к каталогу, а dest не существует, рекурсивно создаёт жёсткие ссылки по адресу dest, указывающие на пути в src:

FileUtils.mkdir_p(['src1/dir0', 'src1/dir1'])
src_file_paths = [
  'src1/dir0/t0.txt',
  'src1/dir0/t1.txt',
  'src1/dir1/t2.txt',
  'src1/dir1/t3.txt',
  ]
FileUtils.touch(src_file_paths)
File.directory?('dest1')        # => true
FileUtils.link_entry('src1', 'dest1')
File.file?('dest1/dir0/t0.txt') # => true
File.file?('dest1/dir0/t1.txt') # => true
File.file?('dest1/dir1/t2.txt') # => true
File.file?('dest1/dir1/t3.txt') # => true

Необязательные аргументы:

  • dereference_root — разыменовывает src, если это символическая ссылка (по умолчанию false).

  • remove_destination — удаляет dest перед созданием ссылок (по умолчанию false).

Вызывает исключение, если dest — путь к существующему файлу или каталогу и не задан необязательный аргумент remove_destination.

Связанный метод: FileUtils.ln (имеет другие параметры).

ln (src, dest, force: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 517
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

Создаёт жёсткие ссылки.

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемы как пути.

Если src — путь к существующему файлу, а dest — путь к несуществующему файлу, создаёт жёсткую ссылку по адресу dest, указывающую на src; возвращает ноль:

Dir.children('tmp0/')                    # => ["t.txt"]
Dir.children('tmp1/')                    # => []
FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk') # => 0
Dir.children('tmp1/')                    # => ["t.lnk"]

Если src — путь к существующему файлу, а dest — путь к существующему каталогу, создаёт жёсткую ссылку по адресу dest/src, указывающую на src; возвращает ноль:

Dir.children('tmp2')               # => ["t.dat"]
Dir.children('tmp3')               # => []
FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0
Dir.children('tmp3')               # => ["t.dat"]

Если src — массив путей к существующим файлам, а dest — путь к существующему каталогу, то для каждого пути target из src создаёт жёсткую ссылку по адресу dest/target, указывающую на target; возвращает src:

Dir.children('tmp4/')                               # => []
FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/') # => ["tmp0/t.txt", "tmp2/t.dat"]
Dir.children('tmp4/')                               # => ["t.dat", "t.txt"]

Именованные аргументы:

  • force: true — перезаписывает dest, если он существует.

  • noop: true — не создаёт ссылки.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true)
    FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true)
    FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/', verbose: true)
    

    Вывод:

    ln tmp0/t.txt tmp1/t.lnk
    ln tmp2/t.dat tmp3
    ln tmp0/t.txt tmp2/t.dat tmp4/

Вызывает исключение, если dest — путь к существующему файлу, а именованный аргумент force не равен true.

Связанный метод: FileUtils.link_entry (имеет другие параметры).

Также имеет псевдоним: link
ln_s (src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 707
def ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
  if relative
    return ln_sr(src, dest, force: force, target_directory: target_directory, noop: noop, verbose: verbose)
  end
  fu_output_message "ln -s#{force ? 'f' : ''}#{
    target_directory ? '' : 'T'} #{[src,dest].flatten.join ' '}" if verbose
  return if noop
  fu_each_src_dest0(src, dest, target_directory) do |s,d|
    remove_file d, true if force
    File.symlink s, d
  end
end

Создаёт символические ссылки.

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемы как пути.

Если src — путь к существующему файлу:

  • Если dest — путь к несуществующему файлу, создаёт символическую ссылку по пути dest, указывающую на src:

    FileUtils.touch('src0.txt')
    File.exist?('dest0.txt')   # => false
    FileUtils.ln_s('src0.txt', 'dest0.txt')
    File.symlink?('dest0.txt') # => true
    
  • Если dest — путь к существующему файлу, создаёт символическую ссылку по пути dest, указывающую на src, только если передан ключевой аргумент force: true (иначе вызывает исключение):

    FileUtils.touch('src1.txt')
    FileUtils.touch('dest1.txt')
    FileUtils.ln_s('src1.txt', 'dest1.txt', force: true)
    FileTest.symlink?('dest1.txt') # => true
    
    FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
    

Если dest — путь к каталогу, создаёт символическую ссылку по пути dest/src, указывающую на src:

FileUtils.touch('src2.txt')
FileUtils.mkdir('destdir2')
FileUtils.ln_s('src2.txt', 'destdir2')
File.symlink?('destdir2/src2.txt') # => true

Если src — массив путей к существующим файлам, а dest — каталог, для каждого дочернего элемента child в src создаёт символическую ссылку dest/child, указывающую на child:

FileUtils.mkdir('srcdir3')
FileUtils.touch('srcdir3/src0.txt')
FileUtils.touch('srcdir3/src1.txt')
FileUtils.mkdir('destdir3')
FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3')
File.symlink?('destdir3/src0.txt') # => true
File.symlink?('destdir3/src1.txt') # => true

Ключевые аргументы:

  • force: true — перезаписывает dest, если он существует.

  • relative: false — создаёт ссылки относительно dest.

  • noop: true — не создаёт ссылки.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true)
    FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true)
    FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3', noop: true, verbose: true)
    

    Вывод:

    ln -s src0.txt dest0.txt
    ln -s src1.txt destdir1
    ln -sf src2.txt dest2.txt
    ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3

Связанный метод: FileUtils.ln_sf.

Также имеет псевдоним: symlink
ln_sf (src, dest, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 726
def ln_sf(src, dest, noop: nil, verbose: nil)
  ln_s src, dest, force: true, noop: noop, verbose: verbose
end

Аналог FileUtils.ln_s, но ключевой аргумент force: true передаётся всегда.

ln_sr (src, dest, target_directory: true, force: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 733
def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
  cmd = "ln -s#{force ? 'f' : ''}#{target_directory ? '' : 'T'}" if verbose
  fu_each_src_dest0(src, dest, target_directory) do |s,d|
    if target_directory
      parent = File.dirname(d)
      destdirs = fu_split_path(parent)
      real_ddirs = fu_split_path(File.realpath(parent))
    else
      destdirs ||= fu_split_path(dest)
      real_ddirs ||= fu_split_path(File.realdirpath(dest))
    end
    srcdirs = fu_split_path(s)
    i = fu_common_components(srcdirs, destdirs)
    n = destdirs.size - i
    n -= 1 unless target_directory
    link1 = fu_clean_components(*Array.new([n, 0].max, '..'), *srcdirs[i..-1])
    begin
      real_sdirs = fu_split_path(File.realdirpath(s)) rescue nil
    rescue
    else
      i = fu_common_components(real_sdirs, real_ddirs)
      n = real_ddirs.size - i
      n -= 1 unless target_directory
      link2 = fu_clean_components(*Array.new([n, 0].max, '..'), *real_sdirs[i..-1])
      link1 = link2 if link1.size > link2.size
    end
    s = File.join(link1)
    fu_output_message [cmd, s, d].flatten.join(' ') if verbose
    next if noop
    remove_file d, true if force
    File.symlink s, d
  end
end

Аналог FileUtils.ln_s, но создаёт ссылки относительно dest.

makedirs (list, mode: nil, noop: nil, verbose: nil)
Псевдоним для: mkdir_p
mkdir (list, mode: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 317
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

Создаёт каталоги по путям из заданного list (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Если ключевые аргументы не заданы, создаёт каталог по каждому path в list, вызывая: Dir.mkdir(path, mode); см. Dir.mkdir:

FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"]
FileUtils.mkdir('tmp4')        # => ["tmp4"]

Ключевые аргументы:

  • mode: mode — также вызывает File.chmod(mode, path); см. File.chmod.

  • noop: true — не создаёт каталоги.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.mkdir(%w[tmp0 tmp1], verbose: true)
    FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
    

    Вывод:

    mkdir tmp0 tmp1
    mkdir -m 700 tmp2 tmp3

Вызывает исключение, если какой-либо путь указывает на существующий файл или каталог либо если по какой-либо причине каталог не удаётся создать.

Связанный метод: FileUtils.mkdir_p.

mkdir_p (list, mode: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 366
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.each do |item|
    path = remove_trailing_slash(item)

    stack = []
    until File.directory?(path) || File.dirname(path) == path
      stack.push path
      path = File.dirname(path)
    end
    stack.reverse_each do |dir|
      begin
        fu_mkdir dir, mode
      rescue SystemCallError
        raise unless File.directory?(dir)
      end
    end
  end

  return *list
end

Создаёт каталоги по путям из заданного list (один путь или массив путей), при необходимости создавая также родительские каталоги; возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Если ключевые аргументы не заданы, создаёт каталог по каждому path в list, а также все необходимые родительские каталоги, вызывая: Dir.mkdir(path, mode); см. Dir.mkdir:

FileUtils.mkdir_p(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
FileUtils.mkdir_p('tmp4/tmp5')             # => ["tmp4/tmp5"]

Ключевые аргументы:

  • mode: mode — также вызывает File.chmod(mode, path); см. File.chmod.

  • noop: true — не создаёт каталоги.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.mkdir_p(%w[tmp0 tmp1], verbose: true)
    FileUtils.mkdir_p(%w[tmp2 tmp3], mode: 0700, verbose: true)
    

    Вывод:

    mkdir -p tmp0 tmp1
    mkdir -p -m 700 tmp2 tmp3

Вызывает исключение, если по какой-либо причине каталог не удаётся создать.

FileUtils.mkpath и FileUtils.makedirs — псевдонимы для FileUtils.mkdir_p.

Связанный метод: FileUtils.mkdir.

Также имеет псевдонимы: 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/fileutils.rb, line 1154
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
        end
      end
      begin
        File.rename s, d
      rescue Errno::EXDEV,
             Errno::EPERM # move from unencrypted to encrypted dir (ext4)
        copy_entry s, d, true
        if secure
          remove_entry_secure s, force
        else
          remove_entry s, force
        end
      end
    rescue SystemCallError
      raise unless force
    end
  end
end

Перемещает записи.

Аргументы src (один путь или массив путей) и dest (один путь) должны быть интерпретируемы как пути.

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

Может привести к локальной уязвимости, если вызвать метод без ключевого аргумента secure: true; см. раздел Как избежать уязвимости TOCTTOU.

Если src — путь к одному файлу или каталогу, а dest не существует, перемещает src в dest:

tree('src0')
# => src0
#    |-- src0.txt
#    `-- src1.txt
File.exist?('dest0') # => false
FileUtils.mv('src0', 'dest0')
File.exist?('src0')  # => false
tree('dest0')
# => dest0
#    |-- src0.txt
#    `-- src1.txt

Если src — массив путей к файлам и каталогам, а dest — путь к каталогу, копирует содержимое каждого пути из массива в dest:

File.file?('src1.txt') # => true
tree('src1')
# => src1
#    |-- src.dat
#    `-- src.txt
Dir.empty?('dest1')    # => true
FileUtils.mv(['src1.txt', 'src1'], 'dest1')
tree('dest1')
# => dest1
#    |-- src1
#    |   |-- src.dat
#    |   `-- src.txt
#    `-- src1.txt

Ключевые аргументы:

  • force: true — если перемещение включает удаление src (то есть если src и dest находятся в разных файловых системах), игнорирует возникшие исключения StandardError и его подклассов.

  • noop: true — не перемещает файлы.

  • secure: true — безопасно удаляет src; подробности см. в разделе FileUtils.remove_entry_secure.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.mv('src0', 'dest0', noop: true, verbose: true)
    FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
    

    Вывод:

    mv src0 dest0
    mv src1.txt src1 dest1
    
Также имеет псевдоним: move
pwd () Показать исходный код
# File lib/fileutils.rb, line 198
def pwd
  Dir.pwd
end

Возвращает строку, содержащую путь к текущему каталогу:

FileUtils.pwd # => "/rdoc/fileutils"

Связанный метод: FileUtils.cd.

Также имеет псевдоним: getwd
remove (list, force: nil, noop: nil, verbose: nil)
Псевдоним для: rm
remove_dir (path, force = false) Показать исходный код
# File lib/fileutils.rb, line 1489
def remove_dir(path, force = false)
  raise Errno::ENOTDIR, path unless force or File.directory?(path)
  remove_entry path, force
end

Рекурсивно удаляет запись каталога, заданную path, которая должна быть записью обычного файла, символической ссылки или каталога.

Аргумент path должен быть интерпретируем как путь.

Необязательный аргумент force задаёт, следует ли игнорировать возникшие исключения StandardError и его подклассов.

Связанные методы: методы удаления.

remove_entry (path, force = false) Показать исходный код
# File lib/fileutils.rb, line 1446
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 должен быть интерпретируем как путь.

Необязательный аргумент force задаёт, следует ли игнорировать возникшие исключения StandardError и его подклассов.

Связанный метод: FileUtils.remove_entry_secure.

remove_entry_secure (path, force = false) Показать исходный код
# File lib/fileutils.rb, line 1348
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
  dot_file = fullpath + "/."
  begin
    File.open(dot_file) {|f|
      unless fu_stat_identical_entry?(st, f.stat)
        # symlink (TOC-to-TOU attack?)
        File.unlink fullpath
        return
      end
      f.chown euid, -1
      f.chmod 0700
    }
  rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
    File.lstat(dot_file).tap {|fstat|
      unless fu_stat_identical_entry?(st, fstat)
        # symlink (TOC-to-TOU attack?)
        File.unlink fullpath
        return
      end
      File.chown euid, -1, dot_file
      File.chmod 0700, dot_file
    }
  end

  unless fu_stat_identical_entry?(st, File.lstat(fullpath))
    # TOC-to-TOU attack?
    File.unlink fullpath
    return
  end

  # ---- tree root is frozen ----
  root = Entry_.new(path)
  root.preorder_traverse do |ent|
    if ent.directory?
      ent.chown euid, -1
      ent.chmod 0700
    end
  end
  root.postorder_traverse do |ent|
    begin
      ent.remove
    rescue
      raise unless force
    end
  end
rescue
  raise unless force
end

Безопасно удаляет запись, заданную path, которая должна быть записью обычного файла, символической ссылки или каталога.

Аргумент path должен быть интерпретируем как путь.

Предотвращает локальную уязвимость, которая может возникнуть при определённых обстоятельствах; см. раздел Как избежать уязвимости TOCTTOU.

Необязательный аргумент force задаёт, следует ли игнорировать возникшие исключения StandardError и его подклассов.

Связанные методы: методы удаления.

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

Удаляет запись файла, заданную path, которая должна быть записью обычного файла или символической ссылки.

Аргумент path должен быть интерпретируем как путь.

Необязательный аргумент force задаёт, следует ли игнорировать возникшие исключения StandardError и его подклассов.

Связанные методы: методы удаления.

rm (list, force: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1213
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 (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Если ключевые аргументы не заданы, удаляет файлы по путям, указанным в list:

FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]

Ключевые аргументы:

  • force: true — игнорирует возникшие исключения StandardError и его подклассов.

  • noop: true — не удаляет файлы; возвращает nil.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
    

    Вывод:

    rm src0.dat src0.txt
    

Связанные методы: методы удаления.

Также имеет псевдоним: remove
rm_f (list, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 1238
def rm_f(list, noop: nil, verbose: nil)
  rm list, force: true, noop: noop, verbose: verbose
end

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

FileUtils.rm(list, force: true, **kwargs)

Аргумент list (один путь или массив путей) должен быть интерпретируем как путь.

Сведения о ключевых аргументах см. в разделе FileUtils.rm.

Связанные методы: методы удаления.

Также имеет псевдоним: safe_unlink
rm_r (list, force: nil, noop: nil, verbose: nil, secure: nil) Показать исходный код
# File lib/fileutils.rb, line 1296
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 (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Может привести к локальной уязвимости, если вызвать метод без ключевого аргумента secure: true; см. раздел Как избежать уязвимости TOCTTOU.

Для каждого пути к файлу удаляет файл по этому пути:

FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm_r(['src0.dat', 'src0.txt'])
File.exist?('src0.txt') # => false
File.exist?('src0.dat') # => false

Для каждого пути к каталогу рекурсивно удаляет файлы и каталоги:

tree('src1')
# => src1
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.rm_r('src1')
File.exist?('src1') # => false

Ключевые аргументы:

  • force: true — игнорирует возникшие исключения StandardError и его подклассов.

  • noop: true — не удаляет записи; возвращает nil.

  • secure: true — безопасно удаляет src; подробности см. в разделе FileUtils.remove_entry_secure.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true)
    FileUtils.rm_r('src1', noop: true, verbose: true)
    

    Вывод:

    rm -r src0.dat src0.txt
    rm -r src1

Связанные методы: методы удаления.

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

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

FileUtils.rm_r(list, force: true, **kwargs)

Аргумент list или его элементы должны быть интерпретируемы как пути.

Может привести к локальной уязвимости, если вызвать метод без ключевого аргумента secure: true; см. раздел Как избежать уязвимости TOCTTOU.

Сведения о ключевых аргументах см. в разделе FileUtils.rm_r.

Связанные методы: методы удаления.

Также имеет псевдоним: rmtree
rmdir (list, parents: nil, noop: nil, verbose: nil) Показать исходный код
# File lib/fileutils.rb, line 443
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|
    Dir.rmdir(dir = remove_trailing_slash(dir))
    if parents
      begin
        until (parent = File.dirname(dir)) == '.' or parent == dir
          dir = parent
          Dir.rmdir(dir)
        end
      rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
      end
    end
  end
end

Удаляет каталоги по путям из заданного list (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Если ключевые аргументы не заданы, удаляет каталог для каждого path в list, вызывая: Dir.rmdir(path); см. Dir.rmdir:

FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
FileUtils.rmdir('tmp4/tmp5')             # => ["tmp4/tmp5"]

Ключевые аргументы:

  • parents: true — удаляет последовательно родительские каталоги, если они пусты.

  • noop: true — не удаляет каталоги.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true)
    FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
    

    Вывод:

    rmdir -p tmp0/tmp1 tmp2/tmp3
    rmdir -p tmp4/tmp5

Вызывает исключение, если каталог не существует или если по какой-либо причине его не удаётся удалить.

Связанные методы: методы удаления.

rmtree (list, noop: nil, verbose: nil, secure: nil)
Псевдоним для: rm_rf
safe_unlink (list, noop: nil, verbose: nil)
Псевдоним для: rm_f
symlink (src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
Псевдоним для: ln_s
touch (list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) Показать исходный код
# File lib/fileutils.rb, line 2004
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 (один путь или массив путей); возвращает list, если это массив, и [list] в противном случае.

По умолчанию для любого пути, указывающего на несуществующую запись, создаёт пустой файл; чтобы вместо этого вызвать исключение, используйте ключевой аргумент nocreate.

Аргумент list или его элементы должны быть интерпретируемы как пути.

Примеры:

# Single path.
f = File.new('src0.txt') # Existing file.
f.atime # => 2022-06-10 11:11:21.200277 -0700
f.mtime # => 2022-06-10 11:11:21.200277 -0700
FileUtils.touch('src0.txt')
f = File.new('src0.txt')
f.atime # => 2022-06-11 08:28:09.8185343 -0700
f.mtime # => 2022-06-11 08:28:09.8185343 -0700

# Array of paths.
FileUtils.touch(['src0.txt', 'src0.dat'])

Ключевые аргументы:

  • mtime: time — задаёт время модификации (mtime) записи равным указанному времени вместо текущего.

  • nocreate: true — вызывает исключение, если запись не существует.

  • noop: true — не изменяет записи; возвращает nil.

  • verbose: true — выводит эквивалентную команду:

    FileUtils.touch('src0.txt', noop: true, verbose: true)
    FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true)
    FileUtils.touch(path, noop: true, verbose: true)
    

    Вывод:

    touch src0.txt
    touch src0.txt src0.dat
    touch src0.txt
    

Связанный метод: FileUtils.uptodate?.

uptodate? (new, old_list) Показать исходный код
# File lib/fileutils.rb, line 265
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; в противном случае возвращает false.

Аргумент new и элементы old_list должны быть интерпретируемы как пути:

FileUtils.uptodate?('Rakefile', ['Gemfile', 'README.md']) # => true
FileUtils.uptodate?('Gemfile', ['Rakefile', 'README.md']) # => false

Несуществующий файл считается бесконечно старым.

Связанный метод: FileUtils.touch.

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

Spec-Zone.ru

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