модуль FileUtils
Пространство имён для методов работы с файлами, таких как копирование, перемещение, удаление и т. д.
Что здесь
Прежде всего, что находится где-то ещё. Модуль FileUtils:
-
Наследуется от класса Object.
-
Дополняет класс File (но не включён и не расширяется там).
Здесь модуль FileUtils предоставляет методы, полезные для:
Создание
-
::mkdir: Создаёт директории. -
::mkdir_p,::makedirs,::mkpath: Создаёт директории, а также создаёт необходимые родительские директории по мере необходимости. -
::link_entry: Создаёт жёсткую ссылку. -
::ln_sf: Создаёт символические ссылки, перезаписывая при необходимости. -
::ln_sr: Создаёт символические ссылки, относящиеся к целевым файлам
Удаление
-
::remove_dir: Удаляет директорию и её потомков. -
::remove_entry: Удаляет запись, включая её потомков, если это директория. -
::remove_entry_secure: Как::remove_entry, но удаляет безопасно. -
::remove_file: Удаляет запись файла. -
::rm_f,::safe_unlink: Как::rm, но удаляет принудительно. -
::rm_r: Удаляет записи и их потомков. -
::rmdir: Удаляет директории.
Запрос
-
::uptodate?: Возвращает, является ли заданная запись более новой, чем другие заданные записи.
Установка
-
::chmod: Устанавливает права доступа для записи. -
::chmod_R: Устанавливает права доступа для записи для записи и её потомков. -
::chown: Устанавливает владельца и группу для записей. -
::chown_R: Устанавливает владельца и группу для записей и их потомков. -
::touch: Устанавливает время изменения и доступа к записям, создавая их при необходимости.
Сравнение
-
::compare_file,::cmp,::identical?: Возвращает, являются ли две записи идентичными. -
::compare_stream: Возвращает, являются ли два потока идентичными.
Копирование
-
::copy_entry: Рекурсивно копирует запись. -
::copy_file: Копирует запись. -
::copy_stream: Копирует поток. -
::cp_lr: Рекурсивно создаёт жёсткие ссылки. -
::cp_r: Рекурсивно копирует файлы, сохраняя режим, владельца и группу. -
::install: Рекурсивно копирует файлы, необязательно устанавливая режим, владельца и группу.
Перемещение
Параметры
-
::collect_method: Возвращает имена методов, принимающих заданный параметр. -
::commands: Возвращает имена методов, принимающих параметры. -
::have_option?: Возвращает, принимает ли данный метод заданный параметр. -
::options: Возвращает все имена параметров. -
::options_of: Возвращает имена параметров для заданного метода.
Аргументы пути
Некоторые методы в FileUtils принимают аргументы пути, которые интерпретируются как пути к записям файловой системы:
-
Если аргумент является строкой, это значение и есть путь.
-
Если аргумент имеет метод
: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
Для определённых методов, рекурсивно удаляющих записи, существует потенциальная уязвимость, называемая уязвимостью «проверка-время-выполнение-время» (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).
ПРЕДУПРЕЖДЕНИЕ: Вы должны гарантировать, что ВСЕ родительские директории не могут быть перемещены другими ненадёжными пользователями. Например, родительские директории не должны принадлежать ненадежным пользователям и не должны быть доступны для записи для всех, кроме случаев, когда установлен битовой атрибут «только для чтения».
Подробности об этой уязвимости безопасности см. в примерах Perl:
Константы
- VERSION
-
Номер версии.
Методы публичного класса
Исходный код
# 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.
Исходный код
# File lib/fileutils.rb, line 1804
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.
Исходный код
# File lib/fileutils.rb, line 1816
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, но изменяет разрешения рекурсивно.
Исходный код
# File lib/fileutils.rb, line 1897
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.
Исходный код
# File lib/fileutils.rb, line 1913
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, но изменяет владельца и группу рекурсивно.
Исходный код
# File lib/fileutils.rb, line 2611
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"]
Исходный код
# File lib/fileutils.rb, line 2572 def self.commands OPT_TABLE.keys end
Возвращает массив имён строк методов FileUtils, принимающих один или более ключевых аргументов:
FileUtils.commands.sort.take(3) # => ["cd", "chdir", "chmod"]
Исходный код
# File lib/fileutils.rb, line 1508
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.
Исходный код
# File lib/fileutils.rb, line 1531
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.
Исходный код
# File lib/fileutils.rb, line 1041
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: true- еслиsrc- символическая ссылка, следует по ссылке. -
preserve: true- сохраняет временные метки файлов. -
remove_destination: true- удаляетdestперед копированием файлов.
Связанно с: методами для копирования.
Исходный код
# File lib/fileutils.rb, line 1077 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: false- еслиsrc- символическая ссылка, не следует по ссылке. -
preserve: true- сохраняет временные метки файлов. -
remove_destination: true- удаляетdestперед копированием файлов.
Связанно с: методами для копирования.
Исходный код
# File lib/fileutils.rb, line 1089 def copy_stream(src, dest) IO.copy_stream(src, dest) end
Копирует поток ввода-вывода src в поток ввода-вывода dest через IO.copy_stream.
Связанно с: методами для копирования.
Исходный код
# File lib/fileutils.rb, line 874
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 - каталог.
Связанно с: методами для копирования.
Исходный код
# 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 не задан.
Связанно с: методами для копирования.
Исходный код
# File lib/fileutils.rb, line 986
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 — путь к файлу.
Связанные: методы для копирования.
Исходный код
# File lib/fileutils.rb, line 2590
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
Исходный код
# File lib/fileutils.rb, line 1610
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
Связанные: методы для копирования.
Исходный код
# File lib/fileutils.rb, line 813
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: true- развязываетsrc, если это символическая ссылка. -
remove_destination: true- удаляетdestперед созданием ссылок.
Вызывает исключение, если dest — путь к существующему файлу или каталогу, и ключевой аргумент remove_destination: true не задан.
Связанные: FileUtils.ln (с другими параметрами).
Исходный код
# 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 (имеет разные параметры).
Исходный код
# 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, noop: noop, verbose: verbose)
end
fu_output_message "ln -s#{force ? 'f' : ''} #{[src,dest].flatten.join ' '}" if verbose
return if noop
fu_each_src_dest0(src, dest) do |s,d|
remove_file d, true if force
File.symlink s, d
end
end Создаёт символические ссылки.
Аргументы 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.
Исходный код
# File lib/fileutils.rb, line 725 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.
Исходный код
# File lib/fileutils.rb, line 732
def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
options = "#{force ? 'f' : ''}#{target_directory ? '' : 'T'}"
dest = File.path(dest)
srcs = Array(src)
link = proc do |s, target_dir_p = true|
s = File.path(s)
if target_dir_p
d = File.join(destdirs = dest, File.basename(s))
else
destdirs = File.dirname(d = dest)
end
destdirs = fu_split_path(File.realpath(destdirs))
if fu_starting_path?(s)
srcdirs = fu_split_path((File.realdirpath(s) rescue File.expand_path(s)))
base = fu_relative_components_from(srcdirs, destdirs)
s = File.join(*base)
else
srcdirs = fu_clean_components(*fu_split_path(s))
base = fu_relative_components_from(fu_split_path(Dir.pwd), destdirs)
while srcdirs.first&. == ".." and base.last&.!=("..") and !fu_starting_path?(base.last)
srcdirs.shift
base.pop
end
s = File.join(*base, *srcdirs)
end
fu_output_message "ln -s#{options} #{s} #{d}" if verbose
next if noop
remove_file d, true if force
File.symlink s, d
end
case srcs.size
when 0
when 1
link[srcs[0], target_directory && File.directory?(dest)]
else
srcs.each(&link)
end
end Подобно FileUtils.ln_s, но создавать ссылки относительно dest.
Исходный код
# 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.
Исходный код
# 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.
Исходный код
# File lib/fileutils.rb, line 1158
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
Исходный код
# File lib/fileutils.rb, line 2580
def self.options
OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
end Возвращает массив имён строковых ключевых слов:
FileUtils.options.take(3) # => ["noop", "verbose", "force"]
Исходный код
# File lib/fileutils.rb, line 2601
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"]
Исходный код
# File lib/fileutils.rb, line 198 def pwd Dir.pwd end
Возвращает строку, содержащую путь к текущей директории:
FileUtils.pwd # => "/rdoc/fileutils"
Связанно с: FileUtils.cd.
Исходный код
# File lib/fileutils.rb, line 1493 def remove_dir(path, force = false) remove_entry path, force # FIXME?? check if it is a directory end
Рекурсивно удаляет запись каталога, заданную path, которая должна быть записью для обычного файла, символической ссылки или каталога.
Аргумент path должен быть интерпретируемым как путь.
Необязательный аргумент force указывает, нужно ли игнорировать возбуждённые исключения StandardError и его потомков.
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1450
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.
Исходный код
# File lib/fileutils.rb, line 1352
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 и его потомков.
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1474 def remove_file(path, force = false) Entry_.new(path).remove_file rescue raise unless force end
Удаляет запись файла, заданную path, которая должна быть записью для обычного файла или символической ссылки.
Аргумент path должен быть интерпретируемым как путь.
Необязательный аргумент force указывает, нужно ли игнорировать возбуждённые исключения StandardError и его потомков.
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1217
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
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1242 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 для ключевых аргументов.
Связанные: методы для удаления.
Исходный код
# File lib/fileutils.rb, line 1300
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
Связанные: методы для удаления.
Исходный код
# File lib/fileutils.rb, line 1329 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 для ключевых аргументов.
Связанные: методы для удаления.
Исходный код
# 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
Вызывает исключение, если каталог не существует или по какой-либо причине не может быть удален.
Связанные: методы для удаления.
Исходный код
# File lib/fileutils.rb, line 2007
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?.
Исходный код
# 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.
Методы частного экземпляра
Исходный код
# 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.
Исходный код
# File lib/fileutils.rb, line 1804
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.
Исходный код
# File lib/fileutils.rb, line 1816
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, но изменяет разрешения рекурсивно.
Исходный код
# File lib/fileutils.rb, line 1897
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может быть именем пользователя или id пользователя; еслиnilили-1, пользователь не изменяется. -
Аргумент
groupможет быть именем группы или id группы; если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.
Исходный код
# File lib/fileutils.rb, line 1913
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, но изменяет владельца и группу рекурсивно.
Исходный код
# File lib/fileutils.rb, line 1508
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.
Исходный код
# File lib/fileutils.rb, line 1531
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.
Исходный код
# File lib/fileutils.rb, line 1041
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: true— еслиsrc— символическая ссылка, следует за ссылкой. -
preserve: true— сохраняет временные метки файлов. -
remove_destination: true— удаляетdestперед копированием файлов.
Связанные: методы для копирования.
Исходный код
# File lib/fileutils.rb, line 1077 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: false— еслиsrc— символическая ссылка, не следует за ссылкой. -
preserve: true— сохраняет временные метки файлов. -
remove_destination: true— удаляетdestперед копированием файлов.
Связанные: методы для копирования.
Исходный код
# File lib/fileutils.rb, line 1089 def copy_stream(src, dest) IO.copy_stream(src, dest) end
Копирует поток ввода-вывода src в поток ввода-вывода dest через IO.copy_stream.
Связанные: методы для копирования.
Исходный код
# File lib/fileutils.rb, line 874
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 — каталог.
Связанные: методы для копирования.
Исходный код
# 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 не задан.
Связанные: методы для копирования.
Исходный код
# File lib/fileutils.rb, line 986
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 — путь к файлу.
Связанные: методы для копирования.
Исходный код
# File lib/fileutils.rb, line 1610
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
Связанные: методы для копирования.
Исходный код
# File lib/fileutils.rb, line 813
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: true- разыменовываетsrc, если это символическая ссылка. -
remove_destination: true- удаляетdestперед созданием ссылок.
Вызывает исключение, если dest является путем к существующему файлу или директории и ключевой аргумент remove_destination: true не задан.
Связанные: FileUtils.ln (имеет другие опции).
Исходный код
# 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 (имеет другие опции).
Исходный код
# 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, noop: noop, verbose: verbose)
end
fu_output_message "ln -s#{force ? 'f' : ''} #{[src,dest].flatten.join ' '}" if verbose
return if noop
fu_each_src_dest0(src, dest) do |s,d|
remove_file d, true if force
File.symlink s, d
end
end Создает символические ссылки.
Аргументы 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.
Исходный код
# File lib/fileutils.rb, line 725 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.
Исходный код
# File lib/fileutils.rb, line 732
def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
options = "#{force ? 'f' : ''}#{target_directory ? '' : 'T'}"
dest = File.path(dest)
srcs = Array(src)
link = proc do |s, target_dir_p = true|
s = File.path(s)
if target_dir_p
d = File.join(destdirs = dest, File.basename(s))
else
destdirs = File.dirname(d = dest)
end
destdirs = fu_split_path(File.realpath(destdirs))
if fu_starting_path?(s)
srcdirs = fu_split_path((File.realdirpath(s) rescue File.expand_path(s)))
base = fu_relative_components_from(srcdirs, destdirs)
s = File.join(*base)
else
srcdirs = fu_clean_components(*fu_split_path(s))
base = fu_relative_components_from(fu_split_path(Dir.pwd), destdirs)
while srcdirs.first&. == ".." and base.last&.!=("..") and !fu_starting_path?(base.last)
srcdirs.shift
base.pop
end
s = File.join(*base, *srcdirs)
end
fu_output_message "ln -s#{options} #{s} #{d}" if verbose
next if noop
remove_file d, true if force
File.symlink s, d
end
case srcs.size
when 0
when 1
link[srcs[0], target_directory && File.directory?(dest)]
else
srcs.each(&link)
end
end Подобно FileUtils.ln_s, но создаёт ссылки, относительные к dest.
Исходный код
# 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.
Исходный код
# 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.
Исходный код
# File lib/fileutils.rb, line 1158
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
Исходный код
# File lib/fileutils.rb, line 198 def pwd Dir.pwd end
Возвращает строку, содержащую путь к текущей директории:
FileUtils.pwd # => "/rdoc/fileutils"
Связанно с: FileUtils.cd.
Исходный код
# File lib/fileutils.rb, line 1493 def remove_dir(path, force = false) remove_entry path, force # FIXME?? check if it is a directory end
Рекурсивно удаляет запись директории, заданную path, которая должна быть записью для обычного файла, символьной ссылки или директории.
Аргумент path должен быть интерпретируем как путь.
Необязательный аргумент force указывает, игнорировать ли поднятые исключения типа StandardError и его потомков.
Связанно с: методами для удаления.
Исходный код
# File lib/fileutils.rb, line 1450
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.
Исходный код
# File lib/fileutils.rb, line 1352
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 и его потомков.
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1474 def remove_file(path, force = false) Entry_.new(path).remove_file rescue raise unless force end
Удаляет запись файла, заданную значением path, которая должна быть записью для обычного файла или символьной ссылки.
Аргумент path должен быть интерпретируемым как путь.
Необязательный аргумент force указывает, нужно ли игнорировать возбуждённые исключения типа StandardError и его потомков.
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1217
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
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1242 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 для ключевых аргументов.
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1300
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
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 1329 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 для ключевых аргументов.
Связанно с: методами удаления.
Исходный код
# 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
Возбуждает исключение, если каталог не существует или по какой-либо причине не может быть удалён.
Связанно с: методами удаления.
Исходный код
# File lib/fileutils.rb, line 2007
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?.
Исходный код
# 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–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.