模块 Bundler::FileUtils
用于复制、移动、删除等文件实用方法的命名空间。
此处内容¶ ↑
首先,了解其他地方的内容。模块 Bundler::FileUtils
-
继承自类 Object。
-
补充了 File 类(但未包含或扩展到该类中)。
在这里,模块 Bundler::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
:返回给定方法的选项名称。
路径参数¶ ↑
Bundler::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
。 -
目标路径上的目录树包括
-
全局可写的后代目录。
-
符号链接。
-
为了避免该漏洞,您可以使用此方法删除条目
-
Bundler::FileUtils.remove_entry_secure
:如果目标路径指向目录,则递归删除。
以下方法也可用,每个方法都调用 Bundler::FileUtils.remove_entry_secure
-
Bundler::FileUtils.rm_r
,带有关键字参数secure: true
。 -
Bundler::FileUtils.rm_rf
,带有关键字参数secure: true
。
最后,此用于移动条目的方法在源和目标位于不同的文件系统上时(这意味着“移动”实际上是复制和删除)调用 Bundler::FileUtils.remove_entry_secure
-
Bundler::FileUtils.mv
,带有关键字参数secure: true
。
方法 Bundler::FileUtils.remove_entry_secure 通过应用特殊的预处理来安全地删除
-
如果目标路径指向目录,则此方法在删除目录时使用 File#chown 和 File#chmod 方法。
-
目标目录的所有者应该是当前进程或超级用户(root)。
警告:您必须确保所有父目录都不能被其他不受信任的用户移动。例如,父目录不应由不受信任的用户拥有,并且除非设置了粘滞位,否则不应全局可写。
有关此安全漏洞的详细信息,请参阅 Perl 案例
常量
- VERSION
版本号。
公共类方法
将工作目录更改为给定的 dir
,该 dir
应解释为路径
如果没有给定块,则将当前目录更改为 dir
处的目录;返回零
Bundler::FileUtils.pwd # => "/rdoc/fileutils" Bundler::FileUtils.cd('..') Bundler::FileUtils.pwd # => "/rdoc" Bundler::FileUtils.cd('fileutils')
如果给定块,则将当前目录更改为 dir
处的目录,使用参数 dir
调用该块,并恢复原始当前目录;返回块的值
Bundler::FileUtils.pwd # => "/rdoc/fileutils" Bundler::FileUtils.cd('..') { |arg| [arg, Bundler::FileUtils.pwd] } # => ["..", "/rdoc"] Bundler::FileUtils.pwd # => "/rdoc/fileutils"
关键字参数
-
verbose: true
- 打印等效的命令Bundler::FileUtils.cd('..') Bundler::FileUtils.cd('fileutils')
输出
cd .. cd fileutils
# File bundler/vendor/fileutils/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
将 list
(单个路径或路径数组)中给定路径处的条目的权限更改为 mode
给定的权限;如果 list
是数组,则返回 list
,否则返回 [list]
-
使用 File.chmod 修改每个是常规文件的条目。
-
使用 File.lchmod 修改每个是符号链接的条目。
参数 list
或其元素应解释为路径。
参数 mode
可以是整数或字符串
-
整数
mode
:表示要设置的权限位Bundler::FileUtils.chmod(0755, 'src0.txt') Bundler::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 位。
-
示例
Bundler::FileUtils.chmod('u=wrx,go=rx', 'src1.txt') Bundler::FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby')
-
关键字参数
-
noop: true
- 不更改权限;返回nil
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.chmod(0755, 'src0.txt', noop: true, verbose: true) Bundler::FileUtils.chmod(0644, ['src0.txt', 'src0.dat'], noop: true, verbose: true) Bundler::FileUtils.chmod('u=wrx,go=rx', 'src1.txt', noop: true, verbose: true) Bundler::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
相关:Bundler::FileUtils.chmod_R
。
# File bundler/vendor/fileutils/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
类似于 Bundler::FileUtils.chmod
,但会递归地更改权限。
# File bundler/vendor/fileutils/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
将 list
(单个路径或路径数组)中给定路径的条目的所有者和组更改为给定的 user
和 group
;如果 list
是数组,则返回 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 Bundler::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. Bundler::FileUtils.chown(1004, 1004, 'src0.txt') File.stat('src0.txt').uid # => 1004 File.stat('src0.txt').gid # => 1004 # Array of paths. Bundler::FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat']) # Directory (not recursive). Bundler::FileUtils.chown('user2', 'group1', '.')
关键字参数
-
noop: true
- 不更改权限;返回nil
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.chown('user2', 'group1', 'src0.txt', noop: true, verbose: true) Bundler::FileUtils.chown(1004, 1004, 'src0.txt', noop: true, verbose: true) Bundler::FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'], noop: true, verbose: true) Bundler::FileUtils.chown('user2', 'group1', path, noop: true, verbose: true) Bundler::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 .
相关:Bundler::FileUtils.chown_R
。
# File bundler/vendor/fileutils/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
类似于 Bundler::FileUtils.chown
,但会递归地更改所有者和组。
# File bundler/vendor/fileutils/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
compare_file
的别名返回一个字符串方法名称数组,这些方法接受给定的关键字选项 opt
;参数必须是符号
Bundler::FileUtils.collect_method(:preserve) # => ["cp", "copy", "cp_r", "install"]
# File bundler/vendor/fileutils/lib/fileutils.rb, line 2611 def self.collect_method(opt) OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) } end
返回一个字符串名称数组,这些名称是接受一个或多个关键字参数的 Bundler::FileUtils 方法的名称
Bundler::FileUtils.commands.sort.take(3) # => ["cd", "chdir", "chmod"]
# File bundler/vendor/fileutils/lib/fileutils.rb, line 2572 def self.commands OPT_TABLE.keys end
如果文件 a
和 b
的内容相同,则返回 true
,否则返回 false
。
参数 a
和 b
应该可解释为路径。
Bundler::FileUtils.identical?
和 Bundler::FileUtils.cmp
是 Bundler::FileUtils.compare_file
的别名。
相关:Bundler::FileUtils.compare_stream
。
# File bundler/vendor/fileutils/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
如果流 a
和 b
的内容相同,则返回 true
,否则返回 false
。
参数 a
和 b
应该可解释为路径。
相关:Bundler::FileUtils.compare_file
。
# File bundler/vendor/fileutils/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
cp
的别名递归地将文件从 src
复制到 dest
。
参数 src
和 dest
应该可解释为路径。
如果 src
是文件的路径,则将 src
复制到 dest
Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::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 Bundler::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 bundler/vendor/fileutils/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
应该可解释为路径。
示例
Bundler::FileUtils.touch('src0.txt') Bundler::FileUtils.copy_file('src0.txt', 'dest0.txt') File.file?('dest0.txt') # => true
关键字参数
-
dereference: false
- 如果src
是符号链接,则不跟随该链接。 -
preserve: true
- 保留文件时间。 -
remove_destination: true
- 在复制文件之前删除dest
。
相关:复制方法。
# File bundler/vendor/fileutils/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
通过 IO.copy_stream 将 IO 流 src
复制到 IO 流 dest
。
相关:复制方法。
# File bundler/vendor/fileutils/lib/fileutils.rb, line 1089 def copy_stream(src, dest) IO.copy_stream(src, dest) end
复制文件。
参数 src
(单个路径或路径数组)和 dest
(单个路径)应该可解释为路径。
如果 src
是文件的路径,并且 dest
不是目录的路径,则将 src
复制到 dest
Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::FileUtils.cp('src0.txt', 'dest0.txt') File.file?('dest0.txt') # => true
如果 src
是文件的路径,并且 dest
是目录的路径,则将 src
复制到 dest/src
Bundler::FileUtils.touch('src1.txt') Bundler::FileUtils.mkdir('dest1') Bundler::FileUtils.cp('src1.txt', 'dest1') File.file?('dest1/src1.txt') # => true
如果 src
是文件路径数组,并且 dest
是目录的路径,则将每个 src
复制到 dest
src_file_paths = ['src2.txt', 'src2.dat'] Bundler::FileUtils.touch(src_file_paths) Bundler::FileUtils.mkdir('dest2') Bundler::FileUtils.cp(src_file_paths, 'dest2') File.file?('dest2/src2.txt') # => true File.file?('dest2/src2.dat') # => true
关键字参数
-
preserve: true
- 保留文件时间。 -
noop: true
- 不复制文件。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true) Bundler::FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true) Bundler::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 bundler/vendor/fileutils/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
链接及其后代
tree('src0') # => src0 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt File.exist?('dest0') # => false Bundler::FileUtils.cp_lr('src0', 'dest0') tree('dest0') # => dest0 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt
如果 src
和 dest
都是目录的路径,则创建指向 src
及其后代的 dest/src
链接及其后代
tree('src1') # => src1 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt Bundler::FileUtils.mkdir('dest1') Bundler::FileUtils.cp_lr('src1', 'dest1') tree('dest1') # => dest1 # `-- src1 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt
如果 src
是条目路径数组,并且 dest
是目录的路径,则对于 src
中的每个路径 filepath
,在 dest/filepath
创建指向该路径的链接
tree('src2') # => src2 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt Bundler::FileUtils.mkdir('dest2') Bundler::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
- 打印等效的命令Bundler::FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true) Bundler::FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true) Bundler::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 bundler/vendor/fileutils/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
(单个路径)应该可解释为路径。
在副本中保留模式、所有者和组;要更改这些内容,请改用 Bundler::FileUtils.install
。
如果 src
是文件的路径,并且 dest
不是目录的路径,则将 src
复制到 dest
Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::FileUtils.cp_r('src0.txt', 'dest0.txt') File.file?('dest0.txt') # => true
如果 src
是文件的路径,并且 dest
是目录的路径,则将 src
复制到 dest/src
Bundler::FileUtils.touch('src1.txt') Bundler::FileUtils.mkdir('dest1') Bundler::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 Bundler::FileUtils.exist?('dest2') # => false Bundler::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 Bundler::FileUtils.mkdir('dest3') Bundler::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
- 打印等效的命令Bundler::FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true) Bundler::FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true) Bundler::FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true) Bundler::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 bundler/vendor/fileutils/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
pwd
的别名如果方法 mid
接受给定的选项 opt
,则返回 true
,否则返回 false
;参数可以是字符串或符号
Bundler::FileUtils.have_option?(:chmod, :noop) # => true Bundler::FileUtils.have_option?('chmod', 'secure') # => false
# File bundler/vendor/fileutils/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
compare_file
的别名复制文件条目。请参阅 install(1)。
参数 src
(单个路径或路径数组)和 dest
(单个路径)应该可解释为路径;
如果 dest
处的条目不存在,则从 src
复制到 dest
File.read('src0.txt') # => "aaa\n" File.exist?('dest0.txt') # => false Bundler::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" Bundler::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" Bundler::FileUtils.install('src2.txt', 'dest2') File.read('dest2/src2.txt') # => "aaa\n"
如果 src
是路径数组,并且 dest
指向目录,则将 src
中的每个路径 path
复制到 dest/path
File.file?('src3.txt') # => true File.file?('src3.dat') # => true Bundler::FileUtils.mkdir('dest3') Bundler::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
- 打印等效的命令Bundler::FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true) Bundler::FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true) Bundler::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 bundler/vendor/fileutils/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
ln
的别名创建硬链接;返回 nil
。
参数 src
和 dest
应该可解释为路径。
如果 src
是一个文件路径,且 dest
不存在,则在 dest
创建一个指向 src
的硬链接。
Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::FileUtils.link_entry('src0.txt', 'dest0.txt') File.file?('dest0.txt') # => true
如果 src
是一个目录路径,且 dest
不存在,则在 dest
递归地创建指向 src
中路径的硬链接。
Bundler::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', ] Bundler::FileUtils.touch(src_file_paths) File.directory?('dest1') # => true Bundler::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
,则引发异常。
相关方法: Bundler::FileUtils.ln
(具有不同的选项)。
# File bundler/vendor/fileutils/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
创建硬链接。
参数 src
(单个路径或路径数组)和 dest
(单个路径)应该可解释为路径。
当 src
是一个已存在的文件路径,且 dest
是一个不存在的文件路径时,会在 dest
创建一个指向 src
的硬链接;返回零。
Dir.children('tmp0/') # => ["t.txt"] Dir.children('tmp1/') # => [] Bundler::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') # => [] Bundler::FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0 Dir.children('tmp3') # => ["t.dat"]
当 src
是一个已存在的文件路径数组,且 dest
是一个已存在的目录路径时,则对于 src
中的每个路径 target
,会在 dest/target
创建一个指向 target
的硬链接;返回 src
。
Dir.children('tmp4/') # => [] Bundler::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
- 打印等效的命令Bundler::FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true) Bundler::FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true) Bundler::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
,则会引发异常。
相关方法: Bundler::FileUtils.link_entry
(具有不同的选项)。
# File bundler/vendor/fileutils/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
的符号链接。Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::FileUtils.ln_s('src0.txt', 'dest0.txt') File.symlink?('dest0.txt') # => true
-
当
dest
是一个已存在的文件路径时,仅当给定了关键字参数force: true
时,才会在dest
创建一个指向src
的符号链接(否则会引发异常)。Bundler::FileUtils.touch('src1.txt') Bundler::FileUtils.touch('dest1.txt') Bundler::FileUtils.ln_s('src1.txt', 'dest1.txt', force: true) FileTest.symlink?('dest1.txt') # => true Bundler::FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
如果 dest
是一个目录路径,则会在 dest/src
创建一个指向 src
的符号链接。
Bundler::FileUtils.touch('src2.txt') Bundler::FileUtils.mkdir('destdir2') Bundler::FileUtils.ln_s('src2.txt', 'destdir2') File.symlink?('destdir2/src2.txt') # => true
如果 src
是一个已存在的文件路径数组,且 dest
是一个目录,则对于 src
中的每个子项 child
,会创建符号链接 dest/child
指向 child
。
Bundler::FileUtils.mkdir('srcdir3') Bundler::FileUtils.touch('srcdir3/src0.txt') Bundler::FileUtils.touch('srcdir3/src1.txt') Bundler::FileUtils.mkdir('destdir3') Bundler::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
- 打印等效的命令Bundler::FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true) Bundler::FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true) Bundler::FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true) Bundler::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
相关方法: Bundler::FileUtils.ln_sf
。
# File bundler/vendor/fileutils/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
类似于 Bundler::FileUtils.ln_s
,但始终给定关键字参数 force: true
。
# File bundler/vendor/fileutils/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
类似于 Bundler::FileUtils.ln_s
,但会创建相对于 dest
的链接。
# File bundler/vendor/fileutils/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
在给定的 list
中的路径(单个路径或路径数组)上创建目录;如果它是数组则返回 list
,否则返回 [list]
。
参数 list
或其元素应解释为路径。
如果没有关键字参数,则通过调用 Dir.mkdir(path, mode)
在 list
中的每个 path
上创建一个目录;请参阅 Dir.mkdir。
Bundler::FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"] Bundler::FileUtils.mkdir('tmp4') # => ["tmp4"]
关键字参数
-
mode: mode
- 也会调用File.chmod(mode, path)
;请参阅 File.chmod。 -
noop: true
- 不创建目录。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.mkdir(%w[tmp0 tmp1], verbose: true) Bundler::FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
输出
mkdir tmp0 tmp1 mkdir -m 700 tmp2 tmp3
如果任何路径指向已存在的文件或目录,或者由于任何原因无法创建目录,则会引发异常。
相关方法: Bundler::FileUtils.mkdir_p
。
# File bundler/vendor/fileutils/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
或其元素应解释为路径。
如果没有关键字参数,则通过调用 Dir.mkdir(path, mode)
在 list
中的每个 path
上创建一个目录,以及任何需要的祖先目录;请参阅 Dir.mkdir。
Bundler::FileUtils.mkdir_p(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"] Bundler::FileUtils.mkdir_p('tmp4/tmp5') # => ["tmp4/tmp5"]
关键字参数
-
mode: mode
- 也会调用File.chmod(mode, path)
;请参阅 File.chmod。 -
noop: true
- 不创建目录。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.mkdir_p(%w[tmp0 tmp1], verbose: true) Bundler::FileUtils.mkdir_p(%w[tmp2 tmp3], mode: 0700, verbose: true)
输出
mkdir -p tmp0 tmp1 mkdir -p -m 700 tmp2 tmp3
如果由于任何原因无法创建目录,则会引发异常。
Bundler::FileUtils.mkpath
和 Bundler::FileUtils.makedirs
是 Bundler::FileUtils.mkdir_p
的别名。
相关方法: Bundler::FileUtils.mkdir
。
# File bundler/vendor/fileutils/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
移动条目。
参数 src
(单个路径或路径数组)和 dest
(单个路径)应该可解释为路径。
如果 src
和 dest
位于不同的文件系统上,则先复制,然后删除 src
。
如果不使用关键字参数 secure: true
调用,可能会导致本地漏洞;请参阅 避免 TOCTTOU 漏洞。
如果 src
是单个文件或目录的路径,且 dest
不存在,则将 src
移动到 dest
。
tree('src0') # => src0 # |-- src0.txt # `-- src1.txt File.exist?('dest0') # => false Bundler::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 Bundler::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
;有关详细信息,请参阅Bundler::FileUtils.remove_entry_secure
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.mv('src0', 'dest0', noop: true, verbose: true) Bundler::FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
输出
mv src0 dest0 mv src1.txt src1 dest1
# File bundler/vendor/fileutils/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
返回字符串关键字名称的数组。
Bundler::FileUtils.options.take(3) # => ["noop", "verbose", "force"]
# File bundler/vendor/fileutils/lib/fileutils.rb, line 2580 def self.options OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s } end
返回方法 mid
的字符串关键字名称的数组;参数可以是字符串或符号。
Bundler::FileUtils.options_of(:rm) # => ["force", "noop", "verbose"] Bundler::FileUtils.options_of('mv') # => ["force", "noop", "verbose", "secure"]
# File bundler/vendor/fileutils/lib/fileutils.rb, line 2601 def self.options_of(mid) OPT_TABLE[mid.to_s].map {|sym| sym.to_s } end
返回一个包含当前目录路径的字符串。
Bundler::FileUtils.pwd # => "/rdoc/fileutils"
相关方法: Bundler::FileUtils.cd
。
# File bundler/vendor/fileutils/lib/fileutils.rb, line 198 def pwd Dir.pwd end
删除由 path
给定的条目,它应该是常规文件、符号链接或目录的条目。
参数 path
应该是可解释为路径。
可选参数 force
指定是否忽略引发的 StandardError 及其子类的异常。
相关方法: Bundler::FileUtils.remove_entry_secure
。
# File bundler/vendor/fileutils/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
应该是可解释为路径。
避免在某些情况下可能存在的本地漏洞;请参阅 避免 TOCTTOU 漏洞。
可选参数 force
指定是否忽略引发的 StandardError 及其子类的异常。
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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, Bundler::FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})" end # freeze tree root euid = Process.euid 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
删除给定 list
中的路径(单个路径或路径数组)处的条目,如果它是数组则返回 list
,否则返回 [list]
。
参数 list
或其元素应解释为路径。
如果没有关键字参数,则删除 list
中给定路径的文件。
Bundler::FileUtils.touch(['src0.txt', 'src0.dat']) Bundler::FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]
关键字参数
-
force: true
- 忽略引发的 StandardError 及其子类的异常。 -
noop: true
- 不删除文件;返回nil
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
输出
rm src0.dat src0.txt
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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
等效于
Bundler::FileUtils.rm(list, force: true, **kwargs)
参数 list
(单个路径或路径数组) 应该是可解释为路径。
有关关键字参数,请参阅 Bundler::FileUtils.rm
。
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/lib/fileutils.rb, line 1242 def rm_f(list, noop: nil, verbose: nil) rm list, force: true, noop: noop, verbose: verbose end
删除给定 list
中路径的条目(可以是单个路径或路径数组);如果 list
是数组,则返回 list
,否则返回 [list]
。
参数 list
或其元素应解释为路径。
如果不使用关键字参数 secure: true
调用,可能会导致本地漏洞;请参阅 避免 TOCTTOU 漏洞。
对于每个文件路径,删除该路径上的文件。
Bundler::FileUtils.touch(['src0.txt', 'src0.dat']) Bundler::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 Bundler::FileUtils.rm_r('src1') File.exist?('src1') # => false
关键字参数
-
force: true
- 忽略引发的 StandardError 及其子类的异常。 -
noop: true
- 不删除条目;返回nil
。 -
secure: true
- 安全地删除src
;有关详细信息,请参阅Bundler::FileUtils.remove_entry_secure
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true) Bundler::FileUtils.rm_r('src1', noop: true, verbose: true)
输出
rm -r src0.dat src0.txt rm -r src1
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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
等效于
Bundler::FileUtils.rm_r(list, force: true, **kwargs)
参数 list
或其元素应解释为路径。
如果不使用关键字参数 secure: true
调用,可能会导致本地漏洞;请参阅 避免 TOCTTOU 漏洞。
有关关键字参数,请参阅 Bundler::FileUtils.rm_r
。
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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
删除给定 list
中路径的目录(可以是单个路径或路径数组);如果 list
是数组,则返回 list
,否则返回 [list]
。
参数 list
或其元素应解释为路径。
如果没有关键字参数,则通过调用 Dir.rmdir(path)
删除 list
中每个 path
的目录;请参阅 Dir.rmdir。
Bundler::FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"] Bundler::FileUtils.rmdir('tmp4/tmp5') # => ["tmp4/tmp5"]
关键字参数
-
parents: true
- 如果上级目录为空,则删除连续的上级目录。 -
noop: true
- 不删除目录。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true) Bundler::FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
输出
rmdir -p tmp0/tmp1 tmp2/tmp3 rmdir -p tmp4/tmp5
如果目录不存在,或者由于任何原因无法删除目录,则会引发异常。
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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
中路径给出的条目的修改时间 (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 Bundler::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. Bundler::FileUtils.touch(['src0.txt', 'src0.dat'])
关键字参数
-
mtime: time
- 将条目的 mtime 设置为给定时间,而不是当前时间。 -
nocreate: true
- 如果条目不存在,则引发异常。 -
noop: true
- 不修改条目;返回nil
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.touch('src0.txt', noop: true, verbose: true) Bundler::FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true) Bundler::FileUtils.touch(path, noop: true, verbose: true)
输出
touch src0.txt touch src0.txt src0.dat touch src0.txt
相关: Bundler::FileUtils.uptodate?
。
# File bundler/vendor/fileutils/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
如果路径 new
上的文件比数组 old_list
中所有路径上的文件都要新,则返回 true
;否则返回 false
。
参数 new
和 old_list
的元素应该是 可解释为路径 的。
Bundler::FileUtils.uptodate?('Rakefile', ['Gemfile', 'README.md']) # => true Bundler::FileUtils.uptodate?('Gemfile', ['Rakefile', 'README.md']) # => false
不存在的文件被认为是无限旧的。
# File bundler/vendor/fileutils/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
私有实例方法
将工作目录更改为给定的 dir
,该 dir
应解释为路径
如果没有给定块,则将当前目录更改为 dir
处的目录;返回零
Bundler::FileUtils.pwd # => "/rdoc/fileutils" Bundler::FileUtils.cd('..') Bundler::FileUtils.pwd # => "/rdoc" Bundler::FileUtils.cd('fileutils')
如果给定块,则将当前目录更改为 dir
处的目录,使用参数 dir
调用该块,并恢复原始当前目录;返回块的值
Bundler::FileUtils.pwd # => "/rdoc/fileutils" Bundler::FileUtils.cd('..') { |arg| [arg, Bundler::FileUtils.pwd] } # => ["..", "/rdoc"] Bundler::FileUtils.pwd # => "/rdoc/fileutils"
关键字参数
-
verbose: true
- 打印等效的命令Bundler::FileUtils.cd('..') Bundler::FileUtils.cd('fileutils')
输出
cd .. cd fileutils
# File bundler/vendor/fileutils/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
将 list
(单个路径或路径数组)中给定路径处的条目的权限更改为 mode
给定的权限;如果 list
是数组,则返回 list
,否则返回 [list]
-
使用 File.chmod 修改每个是常规文件的条目。
-
使用 File.lchmod 修改每个是符号链接的条目。
参数 list
或其元素应解释为路径。
参数 mode
可以是整数或字符串
-
整数
mode
:表示要设置的权限位Bundler::FileUtils.chmod(0755, 'src0.txt') Bundler::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 位。
-
示例
Bundler::FileUtils.chmod('u=wrx,go=rx', 'src1.txt') Bundler::FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby')
-
关键字参数
-
noop: true
- 不更改权限;返回nil
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.chmod(0755, 'src0.txt', noop: true, verbose: true) Bundler::FileUtils.chmod(0644, ['src0.txt', 'src0.dat'], noop: true, verbose: true) Bundler::FileUtils.chmod('u=wrx,go=rx', 'src1.txt', noop: true, verbose: true) Bundler::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
相关:Bundler::FileUtils.chmod_R
。
# File bundler/vendor/fileutils/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
类似于 Bundler::FileUtils.chmod
,但会递归地更改权限。
# File bundler/vendor/fileutils/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
将 list
(单个路径或路径数组)中给定路径的条目的所有者和组更改为给定的 user
和 group
;如果 list
是数组,则返回 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 Bundler::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. Bundler::FileUtils.chown(1004, 1004, 'src0.txt') File.stat('src0.txt').uid # => 1004 File.stat('src0.txt').gid # => 1004 # Array of paths. Bundler::FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat']) # Directory (not recursive). Bundler::FileUtils.chown('user2', 'group1', '.')
关键字参数
-
noop: true
- 不更改权限;返回nil
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.chown('user2', 'group1', 'src0.txt', noop: true, verbose: true) Bundler::FileUtils.chown(1004, 1004, 'src0.txt', noop: true, verbose: true) Bundler::FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'], noop: true, verbose: true) Bundler::FileUtils.chown('user2', 'group1', path, noop: true, verbose: true) Bundler::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 .
相关:Bundler::FileUtils.chown_R
。
# File bundler/vendor/fileutils/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
类似于 Bundler::FileUtils.chown
,但会递归地更改所有者和组。
# File bundler/vendor/fileutils/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
compare_file
的别名如果文件 a
和 b
的内容相同,则返回 true
,否则返回 false
。
参数 a
和 b
应该可解释为路径。
Bundler::FileUtils.identical?
和 Bundler::FileUtils.cmp
是 Bundler::FileUtils.compare_file
的别名。
相关:Bundler::FileUtils.compare_stream
。
# File bundler/vendor/fileutils/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
如果流 a
和 b
的内容相同,则返回 true
,否则返回 false
。
参数 a
和 b
应该可解释为路径。
相关:Bundler::FileUtils.compare_file
。
# File bundler/vendor/fileutils/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
cp
的别名递归地将文件从 src
复制到 dest
。
参数 src
和 dest
应该可解释为路径。
如果 src
是文件的路径,则将 src
复制到 dest
Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::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 Bundler::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 bundler/vendor/fileutils/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
应该可解释为路径。
示例
Bundler::FileUtils.touch('src0.txt') Bundler::FileUtils.copy_file('src0.txt', 'dest0.txt') File.file?('dest0.txt') # => true
关键字参数
-
dereference: false
- 如果src
是符号链接,则不跟随该链接。 -
preserve: true
- 保留文件时间。 -
remove_destination: true
- 在复制文件之前删除dest
。
相关:复制方法。
# File bundler/vendor/fileutils/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
通过 IO.copy_stream 将 IO 流 src
复制到 IO 流 dest
。
相关:复制方法。
# File bundler/vendor/fileutils/lib/fileutils.rb, line 1089 def copy_stream(src, dest) IO.copy_stream(src, dest) end
复制文件。
参数 src
(单个路径或路径数组)和 dest
(单个路径)应该可解释为路径。
如果 src
是文件的路径,并且 dest
不是目录的路径,则将 src
复制到 dest
Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::FileUtils.cp('src0.txt', 'dest0.txt') File.file?('dest0.txt') # => true
如果 src
是文件的路径,并且 dest
是目录的路径,则将 src
复制到 dest/src
Bundler::FileUtils.touch('src1.txt') Bundler::FileUtils.mkdir('dest1') Bundler::FileUtils.cp('src1.txt', 'dest1') File.file?('dest1/src1.txt') # => true
如果 src
是文件路径数组,并且 dest
是目录的路径,则将每个 src
复制到 dest
src_file_paths = ['src2.txt', 'src2.dat'] Bundler::FileUtils.touch(src_file_paths) Bundler::FileUtils.mkdir('dest2') Bundler::FileUtils.cp(src_file_paths, 'dest2') File.file?('dest2/src2.txt') # => true File.file?('dest2/src2.dat') # => true
关键字参数
-
preserve: true
- 保留文件时间。 -
noop: true
- 不复制文件。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true) Bundler::FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true) Bundler::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 bundler/vendor/fileutils/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
链接及其后代
tree('src0') # => src0 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt File.exist?('dest0') # => false Bundler::FileUtils.cp_lr('src0', 'dest0') tree('dest0') # => dest0 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt
如果 src
和 dest
都是目录的路径,则创建指向 src
及其后代的 dest/src
链接及其后代
tree('src1') # => src1 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt Bundler::FileUtils.mkdir('dest1') Bundler::FileUtils.cp_lr('src1', 'dest1') tree('dest1') # => dest1 # `-- src1 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt
如果 src
是条目路径数组,并且 dest
是目录的路径,则对于 src
中的每个路径 filepath
,在 dest/filepath
创建指向该路径的链接
tree('src2') # => src2 # |-- sub0 # | |-- src0.txt # | `-- src1.txt # `-- sub1 # |-- src2.txt # `-- src3.txt Bundler::FileUtils.mkdir('dest2') Bundler::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
- 打印等效的命令Bundler::FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true) Bundler::FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true) Bundler::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 bundler/vendor/fileutils/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
(单个路径)应该可解释为路径。
在副本中保留模式、所有者和组;要更改这些内容,请改用 Bundler::FileUtils.install
。
如果 src
是文件的路径,并且 dest
不是目录的路径,则将 src
复制到 dest
Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::FileUtils.cp_r('src0.txt', 'dest0.txt') File.file?('dest0.txt') # => true
如果 src
是文件的路径,并且 dest
是目录的路径,则将 src
复制到 dest/src
Bundler::FileUtils.touch('src1.txt') Bundler::FileUtils.mkdir('dest1') Bundler::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 Bundler::FileUtils.exist?('dest2') # => false Bundler::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 Bundler::FileUtils.mkdir('dest3') Bundler::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
- 打印等效的命令Bundler::FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true) Bundler::FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true) Bundler::FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true) Bundler::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 bundler/vendor/fileutils/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
pwd
的别名compare_file
的别名复制文件条目。请参阅 install(1)。
参数 src
(单个路径或路径数组)和 dest
(单个路径)应该可解释为路径;
如果 dest
处的条目不存在,则从 src
复制到 dest
File.read('src0.txt') # => "aaa\n" File.exist?('dest0.txt') # => false Bundler::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" Bundler::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" Bundler::FileUtils.install('src2.txt', 'dest2') File.read('dest2/src2.txt') # => "aaa\n"
如果 src
是路径数组,并且 dest
指向目录,则将 src
中的每个路径 path
复制到 dest/path
File.file?('src3.txt') # => true File.file?('src3.dat') # => true Bundler::FileUtils.mkdir('dest3') Bundler::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
- 打印等效的命令Bundler::FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true) Bundler::FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true) Bundler::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 bundler/vendor/fileutils/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
ln
的别名创建硬链接;返回 nil
。
参数 src
和 dest
应该可解释为路径。
如果 src
是一个文件路径,且 dest
不存在,则在 dest
创建一个指向 src
的硬链接。
Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::FileUtils.link_entry('src0.txt', 'dest0.txt') File.file?('dest0.txt') # => true
如果 src
是一个目录路径,且 dest
不存在,则在 dest
递归地创建指向 src
中路径的硬链接。
Bundler::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', ] Bundler::FileUtils.touch(src_file_paths) File.directory?('dest1') # => true Bundler::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
,则引发异常。
相关方法: Bundler::FileUtils.ln
(具有不同的选项)。
# File bundler/vendor/fileutils/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
创建硬链接。
参数 src
(单个路径或路径数组)和 dest
(单个路径)应该可解释为路径。
当 src
是一个已存在的文件路径,且 dest
是一个不存在的文件路径时,会在 dest
创建一个指向 src
的硬链接;返回零。
Dir.children('tmp0/') # => ["t.txt"] Dir.children('tmp1/') # => [] Bundler::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') # => [] Bundler::FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0 Dir.children('tmp3') # => ["t.dat"]
当 src
是一个已存在的文件路径数组,且 dest
是一个已存在的目录路径时,则对于 src
中的每个路径 target
,会在 dest/target
创建一个指向 target
的硬链接;返回 src
。
Dir.children('tmp4/') # => [] Bundler::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
- 打印等效的命令Bundler::FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true) Bundler::FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true) Bundler::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
,则会引发异常。
相关方法: Bundler::FileUtils.link_entry
(具有不同的选项)。
# File bundler/vendor/fileutils/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
的符号链接。Bundler::FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false Bundler::FileUtils.ln_s('src0.txt', 'dest0.txt') File.symlink?('dest0.txt') # => true
-
当
dest
是一个已存在的文件路径时,仅当给定了关键字参数force: true
时,才会在dest
创建一个指向src
的符号链接(否则会引发异常)。Bundler::FileUtils.touch('src1.txt') Bundler::FileUtils.touch('dest1.txt') Bundler::FileUtils.ln_s('src1.txt', 'dest1.txt', force: true) FileTest.symlink?('dest1.txt') # => true Bundler::FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
如果 dest
是一个目录路径,则会在 dest/src
创建一个指向 src
的符号链接。
Bundler::FileUtils.touch('src2.txt') Bundler::FileUtils.mkdir('destdir2') Bundler::FileUtils.ln_s('src2.txt', 'destdir2') File.symlink?('destdir2/src2.txt') # => true
如果 src
是一个已存在的文件路径数组,且 dest
是一个目录,则对于 src
中的每个子项 child
,会创建符号链接 dest/child
指向 child
。
Bundler::FileUtils.mkdir('srcdir3') Bundler::FileUtils.touch('srcdir3/src0.txt') Bundler::FileUtils.touch('srcdir3/src1.txt') Bundler::FileUtils.mkdir('destdir3') Bundler::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
- 打印等效的命令Bundler::FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true) Bundler::FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true) Bundler::FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true) Bundler::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
相关方法: Bundler::FileUtils.ln_sf
。
# File bundler/vendor/fileutils/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
类似于 Bundler::FileUtils.ln_s
,但始终给定关键字参数 force: true
。
# File bundler/vendor/fileutils/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
类似于 Bundler::FileUtils.ln_s
,但会创建相对于 dest
的链接。
# File bundler/vendor/fileutils/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
在给定的 list
中的路径(单个路径或路径数组)上创建目录;如果它是数组则返回 list
,否则返回 [list]
。
参数 list
或其元素应解释为路径。
如果没有关键字参数,则通过调用 Dir.mkdir(path, mode)
在 list
中的每个 path
上创建一个目录;请参阅 Dir.mkdir。
Bundler::FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"] Bundler::FileUtils.mkdir('tmp4') # => ["tmp4"]
关键字参数
-
mode: mode
- 也会调用File.chmod(mode, path)
;请参阅 File.chmod。 -
noop: true
- 不创建目录。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.mkdir(%w[tmp0 tmp1], verbose: true) Bundler::FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
输出
mkdir tmp0 tmp1 mkdir -m 700 tmp2 tmp3
如果任何路径指向已存在的文件或目录,或者由于任何原因无法创建目录,则会引发异常。
相关方法: Bundler::FileUtils.mkdir_p
。
# File bundler/vendor/fileutils/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
或其元素应解释为路径。
如果没有关键字参数,则通过调用 Dir.mkdir(path, mode)
在 list
中的每个 path
上创建一个目录,以及任何需要的祖先目录;请参阅 Dir.mkdir。
Bundler::FileUtils.mkdir_p(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"] Bundler::FileUtils.mkdir_p('tmp4/tmp5') # => ["tmp4/tmp5"]
关键字参数
-
mode: mode
- 也会调用File.chmod(mode, path)
;请参阅 File.chmod。 -
noop: true
- 不创建目录。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.mkdir_p(%w[tmp0 tmp1], verbose: true) Bundler::FileUtils.mkdir_p(%w[tmp2 tmp3], mode: 0700, verbose: true)
输出
mkdir -p tmp0 tmp1 mkdir -p -m 700 tmp2 tmp3
如果由于任何原因无法创建目录,则会引发异常。
Bundler::FileUtils.mkpath
和 Bundler::FileUtils.makedirs
是 Bundler::FileUtils.mkdir_p
的别名。
相关方法: Bundler::FileUtils.mkdir
。
# File bundler/vendor/fileutils/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
移动条目。
参数 src
(单个路径或路径数组)和 dest
(单个路径)应该可解释为路径。
如果 src
和 dest
位于不同的文件系统上,则先复制,然后删除 src
。
如果不使用关键字参数 secure: true
调用,可能会导致本地漏洞;请参阅 避免 TOCTTOU 漏洞。
如果 src
是单个文件或目录的路径,且 dest
不存在,则将 src
移动到 dest
。
tree('src0') # => src0 # |-- src0.txt # `-- src1.txt File.exist?('dest0') # => false Bundler::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 Bundler::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
;有关详细信息,请参阅Bundler::FileUtils.remove_entry_secure
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.mv('src0', 'dest0', noop: true, verbose: true) Bundler::FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
输出
mv src0 dest0 mv src1.txt src1 dest1
# File bundler/vendor/fileutils/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
返回一个包含当前目录路径的字符串。
Bundler::FileUtils.pwd # => "/rdoc/fileutils"
相关方法: Bundler::FileUtils.cd
。
# File bundler/vendor/fileutils/lib/fileutils.rb, line 198 def pwd Dir.pwd end
删除由 path
给定的条目,它应该是常规文件、符号链接或目录的条目。
参数 path
应该是可解释为路径。
可选参数 force
指定是否忽略引发的 StandardError 及其子类的异常。
相关方法: Bundler::FileUtils.remove_entry_secure
。
# File bundler/vendor/fileutils/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
应该是可解释为路径。
避免在某些情况下可能存在的本地漏洞;请参阅 避免 TOCTTOU 漏洞。
可选参数 force
指定是否忽略引发的 StandardError 及其子类的异常。
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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, Bundler::FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})" end # freeze tree root euid = Process.euid 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
删除给定 list
中的路径(单个路径或路径数组)处的条目,如果它是数组则返回 list
,否则返回 [list]
。
参数 list
或其元素应解释为路径。
如果没有关键字参数,则删除 list
中给定路径的文件。
Bundler::FileUtils.touch(['src0.txt', 'src0.dat']) Bundler::FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]
关键字参数
-
force: true
- 忽略引发的 StandardError 及其子类的异常。 -
noop: true
- 不删除文件;返回nil
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
输出
rm src0.dat src0.txt
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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
等效于
Bundler::FileUtils.rm(list, force: true, **kwargs)
参数 list
(单个路径或路径数组) 应该是可解释为路径。
有关关键字参数,请参阅 Bundler::FileUtils.rm
。
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/lib/fileutils.rb, line 1242 def rm_f(list, noop: nil, verbose: nil) rm list, force: true, noop: noop, verbose: verbose end
删除给定 list
中路径的条目(可以是单个路径或路径数组);如果 list
是数组,则返回 list
,否则返回 [list]
。
参数 list
或其元素应解释为路径。
如果不使用关键字参数 secure: true
调用,可能会导致本地漏洞;请参阅 避免 TOCTTOU 漏洞。
对于每个文件路径,删除该路径上的文件。
Bundler::FileUtils.touch(['src0.txt', 'src0.dat']) Bundler::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 Bundler::FileUtils.rm_r('src1') File.exist?('src1') # => false
关键字参数
-
force: true
- 忽略引发的 StandardError 及其子类的异常。 -
noop: true
- 不删除条目;返回nil
。 -
secure: true
- 安全地删除src
;有关详细信息,请参阅Bundler::FileUtils.remove_entry_secure
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true) Bundler::FileUtils.rm_r('src1', noop: true, verbose: true)
输出
rm -r src0.dat src0.txt rm -r src1
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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
等效于
Bundler::FileUtils.rm_r(list, force: true, **kwargs)
参数 list
或其元素应解释为路径。
如果不使用关键字参数 secure: true
调用,可能会导致本地漏洞;请参阅 避免 TOCTTOU 漏洞。
有关关键字参数,请参阅 Bundler::FileUtils.rm_r
。
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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
删除给定 list
中路径的目录(可以是单个路径或路径数组);如果 list
是数组,则返回 list
,否则返回 [list]
。
参数 list
或其元素应解释为路径。
如果没有关键字参数,则通过调用 Dir.rmdir(path)
删除 list
中每个 path
的目录;请参阅 Dir.rmdir。
Bundler::FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"] Bundler::FileUtils.rmdir('tmp4/tmp5') # => ["tmp4/tmp5"]
关键字参数
-
parents: true
- 如果上级目录为空,则删除连续的上级目录。 -
noop: true
- 不删除目录。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true) Bundler::FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
输出
rmdir -p tmp0/tmp1 tmp2/tmp3 rmdir -p tmp4/tmp5
如果目录不存在,或者由于任何原因无法删除目录,则会引发异常。
相关方法: 用于删除的方法。
# File bundler/vendor/fileutils/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
中路径给出的条目的修改时间 (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 Bundler::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. Bundler::FileUtils.touch(['src0.txt', 'src0.dat'])
关键字参数
-
mtime: time
- 将条目的 mtime 设置为给定时间,而不是当前时间。 -
nocreate: true
- 如果条目不存在,则引发异常。 -
noop: true
- 不修改条目;返回nil
。 -
verbose: true
- 打印等效的命令Bundler::FileUtils.touch('src0.txt', noop: true, verbose: true) Bundler::FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true) Bundler::FileUtils.touch(path, noop: true, verbose: true)
输出
touch src0.txt touch src0.txt src0.dat touch src0.txt
相关: Bundler::FileUtils.uptodate?
。
# File bundler/vendor/fileutils/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
如果路径 new
上的文件比数组 old_list
中所有路径上的文件都要新,则返回 true
;否则返回 false
。
参数 new
和 old_list
的元素应该是 可解释为路径 的。
Bundler::FileUtils.uptodate?('Rakefile', ['Gemfile', 'README.md']) # => true Bundler::FileUtils.uptodate?('Gemfile', ['Rakefile', 'README.md']) # => false
不存在的文件被认为是无限旧的。
# File bundler/vendor/fileutils/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