模組 FileUtils

用於複製、移動、移除等檔案工具方法的命名空間。

此處內容

首先,其他位置的內容。模組 FileUtils

此處,模組 FileUtils 提供對下列操作有用的方法

建立

刪除

查詢

設定

比較

複製

移動

選項

路徑引數

FileUtils 中的一些方法接受路徑引數,這些引數會被解釋為檔案系統條目的路徑

關於範例

這裡的一些範例涉及檔案條目的樹狀結構。對於這些範例,我們有時會使用 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,漏洞可能存在於下列情況:

若要避免該漏洞,您可以使用此方法來移除條目

以下這些方法也可以使用,每個方法都會呼叫 FileUtils.remove_entry_secure

最後,此用於移動條目的方法會在來源和目的地位於不同的檔案系統上時呼叫 FileUtils.remove_entry_secure(表示「移動」實際上是複製和移除)

方法 FileUtils.remove_entry_secure 會透過套用特殊的前置處理來安全移除

警告:您必須確保所有父目錄都無法被其他不受信任的使用者移動。例如,父目錄不應由不受信任的使用者擁有,也不應具有世界寫入權限,除非已設定黏著位元。

有關此安全性漏洞的詳細資訊,請參閱 Perl 案例

常數

VERSION

公開類別方法

cd(dir, verbose: nil) { |dir| ... } 按一下以切換來源

將工作目錄變更為指定的 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 238
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
別名:chdir
chdir(dir, verbose: nil)
別名:cd
chmod(mode, list, noop: nil, verbose: nil) 按一下以切換來源

list(單一路徑或路徑陣列)中給定路徑的項目權限變更為 mode 給定的權限;如果 list 是陣列,則傳回 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 1803
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
chmod_R(mode, list, noop: nil, verbose: nil, force: nil) 按一下以切換來源

類似 FileUtils.chmod,但遞迴變更權限。

# File lib/fileutils.rb, line 1815
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
chown(user, group, list, noop: nil, verbose: nil) 按一下以切換來源

變更 list (單一路徑或路徑陣列) 中路徑所指定項目的擁有者和群組,變更為指定的 usergroup;如果 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
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 1896
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
chown_R(user, group, list, noop: nil, verbose: nil, force: nil) 按一下以切換來源

類似 FileUtils.chown,但遞迴變更擁有者和群組。

# File lib/fileutils.rb, line 1912
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
cmp(a, b)
別名:compare_file
collect_method(opt) 按一下以切換來源

傳回接受指定關鍵字選項 opt 的方法的字串方法名稱陣列;引數必須是符號

FileUtils.collect_method(:preserve) # => ["cp", "copy", "cp_r", "install"]
# File lib/fileutils.rb, line 2609
def self.collect_method(opt)
  OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }
end
commands() 按一下以切換來源

傳回接受一個或多個關鍵字引數的 FileUtils 方法的字串名稱陣列

FileUtils.commands.sort.take(3) # => ["cd", "chdir", "chmod"]
# File lib/fileutils.rb, line 2570
def self.commands
  OPT_TABLE.keys
end
compare_file(a, b) 按一下以切換來源

如果檔案 ab 的內容相同,則傳回 true,否則傳回 false

引數 ab可解譯為路徑

FileUtils.identical?FileUtils.cmpFileUtils.compare_file 的別名。

相關:FileUtils.compare_stream

# File lib/fileutils.rb, line 1507
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
也別名為:identical?cmp
compare_stream(a, b) 按一下以切換來源

如果串流 ab 的內容相同,則傳回 true,否則傳回 false

引數 ab可解譯為路徑

相關:FileUtils.compare_file

# File lib/fileutils.rb, line 1530
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
copy(src, dest, preserve: nil, noop: nil, verbose: nil)
別名:cp
copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) 按一下以切換來源

遞迴地將檔案從 src 複製到 dest

參數 srcdest可詮釋為路徑

如果 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 1040
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
copy_file(src, dest, preserve = false, dereference = true) 按一下以切換來源

將檔案從 src 複製到 dest,它們不應是目錄。

參數 srcdest可詮釋為路徑

範例

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 1076
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
copy_stream(src, dest) 按一下以切換來源

透過 IO.copy_stream 將 IO 串流 src 複製到 IO 串流 dest

相關:複製方法

# File lib/fileutils.rb, line 1088
def copy_stream(src, dest)
  IO.copy_stream(src, dest)
end
cp(src, dest, preserve: nil, noop: nil, verbose: nil) 按一下以切換來源

複製檔案。

參數 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 873
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
別名:copy
cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false) 按一下以切換來源

建立 硬連結

參數 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

如果 srcdest 都是目錄路徑,則建立連結 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 是目錄路徑,則針對 src 中的每個路徑 filepath,在 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 627
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
cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) 按一下以切換來源

遞迴複製檔案。

參數 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 不存在,則遞迴複製 srcdest

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

如果 srcdest 是目錄路徑,則遞迴複製 srcdest/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 中的每個路徑遞迴複製到 destsrc 中的路徑可以指向檔案和/或目錄。

關鍵字引數

  • 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 985
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
getwd()
別名:pwd
have_option?(mid, opt) 按一下以切換來源

如果方法 mid 接受指定的選項 opt,則傳回 true,否則傳回 false;參數可以是字串或符號

FileUtils.have_option?(:chmod, :noop) # => true
FileUtils.have_option?('chmod', 'secure') # => false
# File lib/fileutils.rb, line 2588
def self.have_option?(mid, opt)
  li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}"
  li.include?(opt)
end
identical?(a, b)
別名:compare_file
install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) 按一下以切換來源

複製檔案項目。請參閱 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 指向目錄,則將 src 中的每個路徑 path 複製到 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 1609
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
link_entry(src, dest, dereference_root = false, remove_destination = false) 按一下以切換來源

建立 硬連結;傳回 nil

參數 srcdest可詮釋為路徑

如果 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 812
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
ln(src, dest, force: nil, noop: nil, verbose: nil) 按一下以切換來源

建立 硬連結

參數 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 是現有目錄的路徑時,則對 src 中的每個路徑 target,在 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 516
def ln(src, dest, force: nil, noop: nil, verbose: nil)
  fu_output_message "ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
  return if noop
  fu_each_src_dest0(src, dest) do |s,d|
    remove_file d, true if force
    File.link s, d
  end
end
別名為:link
ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil) 按一下以切換來源

建立符號連結

參數 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 是現有檔案的路徑時,如果且僅當給定關鍵字引數 force: true 時,在 dest 建立符號連結,指向 src(否則會引發例外狀況)

    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 是目錄,則對 src 中的每個子項 child,建立符號連結 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 706
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
別名為:symlink
ln_sf(src, dest, noop: nil, verbose: nil) 按一下以切換來源

類似於FileUtils.ln_s,但總是給定關鍵字引數 force: true

# File lib/fileutils.rb, line 724
def ln_sf(src, dest, noop: nil, verbose: nil)
  ln_s src, dest, force: true, noop: noop, verbose: verbose
end
ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil) 按一下以切換來源

類似於FileUtils.ln_s,但相對於 dest 建立連結。

# File lib/fileutils.rb, line 731
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
makedirs(list, mode: nil, noop: nil, verbose: nil)
別名為:mkdir_p
mkdir(list, mode: nil, noop: nil, verbose: nil) 按一下以切換來源

在給定的 list (單一路徑或路徑陣列) 中的路徑建立目錄;如果它是陣列,傳回 list,否則傳回 [list]

引數 list 或其元素應可 詮釋為路徑

如果沒有關鍵字參數,則透過呼叫 Dir.mkdir(path, mode)list 中的每個 path 建立目錄;請參閱 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 316
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
mkdir_p(list, mode: nil, noop: nil, verbose: nil) 按一下以切換來源

在給定的 list (單一路徑或路徑陣列) 中的路徑建立目錄,並視需要建立祖先目錄;如果它是陣列,傳回 list,否則傳回 [list]

引數 list 或其元素應可 詮釋為路徑

如果沒有關鍵字參數,則透過呼叫 Dir.mkdir(path, mode)list 中的每個 path,以及任何必要的祖先目錄建立目錄;請參閱 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.mkpathFileUtils.makedirsFileUtils.mkdir_p 的別名。

相關:FileUtils.mkdir

# File lib/fileutils.rb, line 365
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
也別名為:mkpathmakedirs
mkpath(list, mode: nil, noop: nil, verbose: nil)
別名為:mkdir_p
move(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
別名:mv
mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) 按一下以切換來源

移動項目。

參數 src(單一路徑或路徑陣列)和 dest(單一路徑)應 可詮釋為路徑

如果 srcdest 在不同的檔案系統上,則會先複製,然後移除 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(也就是如果 srcdest 在不同的檔案系統上),則忽略引發的 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 1157
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
別名為:move
options() 按一下以切換來源

傳回字串關鍵字名稱的陣列

FileUtils.options.take(3) # => ["noop", "verbose", "force"]
# File lib/fileutils.rb, line 2578
def self.options
  OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
end
options_of(mid) 按一下以切換來源

傳回方法 mid 的字串關鍵字名稱陣列;引數可以是字串或符號

FileUtils.options_of(:rm) # => ["force", "noop", "verbose"]
FileUtils.options_of('mv') # => ["force", "noop", "verbose", "secure"]
# File lib/fileutils.rb, line 2599
def self.options_of(mid)
  OPT_TABLE[mid.to_s].map {|sym| sym.to_s }
end
pwd() 按一下以切換來源

傳回包含目前目錄路徑的字串

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

相關:FileUtils.cd

# File lib/fileutils.rb, line 197
def pwd
  Dir.pwd
end
別名為:getwd
remove(list, force: nil, noop: nil, verbose: nil)
別名為:rm
remove_dir(path, force = false) 按一下以切換來源

遞迴移除 path 給出的目錄項目,它應該是常規檔案、符號連結或目錄的項目。

引數 path可解釋為路徑

選用引數 force 指定是否忽略引發的 StandardError 和其後代的例外狀況。

相關:刪除方法

# File lib/fileutils.rb, line 1492
def remove_dir(path, force = false)
  remove_entry path, force   # FIXME?? check if it is a directory
end
remove_entry(path, force = false) 按一下以切換來源

移除 path 給出的項目,它應該是常規檔案、符號連結或目錄的項目。

引數 path可解釋為路徑

選用引數 force 指定是否忽略引發的 StandardError 和其後代的例外狀況。

相關:FileUtils.remove_entry_secure

# File lib/fileutils.rb, line 1449
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
remove_entry_secure(path, force = false) 按一下以切換來源

安全地移除 path 給出的項目,它應該是常規檔案、符號連結或目錄的項目。

引數 path可解釋為路徑

避免在某些情況下可能存在的本地漏洞;請參閱 避免 TOCTTOU 漏洞

選用引數 force 指定是否忽略引發的 StandardError 和其後代的例外狀況。

相關:刪除方法

# File lib/fileutils.rb, line 1351
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
remove_file(path, force = false) 按一下以切換來源

移除 path 給出的檔案項目,它應該是常規檔案或符號連結的項目。

引數 path可解釋為路徑

選用引數 force 指定是否忽略引發的 StandardError 和其後代的例外狀況。

相關:刪除方法

# File lib/fileutils.rb, line 1473
def remove_file(path, force = false)
  Entry_.new(path).remove_file
rescue
  raise unless force
end
rm(list, force: nil, noop: nil, verbose: nil) 按一下以切換來源

移除給定 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 1216
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
別名為:remove
rm_f(list, noop: nil, verbose: nil) 按一下以切換來源

等於

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

參數 list(單一路徑或路徑陣列)應 可詮釋為路徑

有關關鍵字參數,請參閱 FileUtils.rm

相關:刪除方法

# File lib/fileutils.rb, line 1241
def rm_f(list, noop: nil, verbose: nil)
  rm list, force: true, noop: noop, verbose: verbose
end
別名為:safe_unlink
rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) 按一下以切換來源

移除給定 list(單一路徑或路徑陣列)中路徑的項目;如果 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 1299
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
rm_rf(list, noop: nil, verbose: nil, secure: nil) 按一下以切換來源

等於

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

引數 list 或其元素應可 詮釋為路徑

如果未呼叫關鍵字參數 secure: true,則可能會造成本機漏洞;請參閱 避免 TOCTTOU 漏洞

有關關鍵字參數,請參閱 FileUtils.rm_r

相關:刪除方法

# File lib/fileutils.rb, line 1328
def rm_rf(list, noop: nil, verbose: nil, secure: nil)
  rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
end
別名為:rmtree
rmdir(list, parents: nil, noop: nil, verbose: nil) 按一下以切換來源

移除給定 list(單一路徑或路徑陣列)中路徑的目錄;如果 list 是陣列,則傳回 list,否則傳回 [list]

引數 list 或其元素應可 詮釋為路徑

如果沒有關鍵字參數,則透過呼叫:Dir.rmdir(path) 來移除 list 中每個 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 442
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
rmtree(list, noop: nil, verbose: nil, secure: nil)
別名為:rm_rf
touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) 按一下以切換來源

更新list(單一路徑或路徑陣列)中路徑所指定條目的修改時間(mtime)和存取時間(atime);如果是陣列,則傳回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 2006
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
uptodate?(new, old_list) 按一下以切換來源

如果路徑new的檔案比陣列old_list中所有路徑的檔案都新,則傳回true;否則傳回false

引數newold_list的元素應可解釋為路徑

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

不存在的檔案視為無限久遠。

相關:FileUtils.touch

# File lib/fileutils.rb, line 264
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

私人實例方法

cd(dir, verbose: nil) { |dir| ... } 按一下以切換來源

將工作目錄變更為指定的 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 238
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
別名:chdir
chdir(dir, verbose: nil)
別名:cd
chmod(mode, list, noop: nil, verbose: nil) 按一下以切換來源

list(單一路徑或路徑陣列)中給定路徑的項目權限變更為 mode 給定的權限;如果 list 是陣列,則傳回 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 1803
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
chmod_R(mode, list, noop: nil, verbose: nil, force: nil) 按一下以切換來源

類似 FileUtils.chmod,但遞迴變更權限。

# File lib/fileutils.rb, line 1815
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
chown(user, group, list, noop: nil, verbose: nil) 按一下以切換來源

變更 list (單一路徑或路徑陣列) 中路徑所指定項目的擁有者和群組,變更為指定的 usergroup;如果 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
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 1896
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
chown_R(user, group, list, noop: nil, verbose: nil, force: nil) 按一下以切換來源

類似 FileUtils.chown,但遞迴變更擁有者和群組。

# File lib/fileutils.rb, line 1912
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
cmp(a, b)
別名:compare_file
compare_file(a, b) 按一下以切換來源

如果檔案 ab 的內容相同,則傳回 true,否則傳回 false

引數 ab可解譯為路徑

FileUtils.identical?FileUtils.cmpFileUtils.compare_file 的別名。

相關:FileUtils.compare_stream

# File lib/fileutils.rb, line 1507
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
也別名為:identical?cmp
compare_stream(a, b) 按一下以切換來源

如果串流 ab 的內容相同,則傳回 true,否則傳回 false

引數 ab可解譯為路徑

相關:FileUtils.compare_file

# File lib/fileutils.rb, line 1530
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
copy(src, dest, preserve: nil, noop: nil, verbose: nil)
別名:cp
copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) 按一下以切換來源

遞迴地將檔案從 src 複製到 dest

參數 srcdest可詮釋為路徑

如果 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 1040
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
copy_file(src, dest, preserve = false, dereference = true) 按一下以切換來源

將檔案從 src 複製到 dest,它們不應是目錄。

參數 srcdest可詮釋為路徑

範例

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 1076
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
copy_stream(src, dest) 按一下以切換來源

透過 IO.copy_stream 將 IO 串流 src 複製到 IO 串流 dest

相關:複製方法

# File lib/fileutils.rb, line 1088
def copy_stream(src, dest)
  IO.copy_stream(src, dest)
end
cp(src, dest, preserve: nil, noop: nil, verbose: nil) 按一下以切換來源

複製檔案。

參數 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 873
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
別名:copy
cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false) 按一下以切換來源

建立 硬連結

參數 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

如果 srcdest 都是目錄路徑,則建立連結 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 是目錄路徑,則針對 src 中的每個路徑 filepath,在 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 627
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
cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil) 按一下以切換來源

遞迴複製檔案。

參數 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 不存在,則遞迴複製 srcdest

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

如果 srcdest 是目錄路徑,則遞迴複製 srcdest/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 中的每個路徑遞迴複製到 destsrc 中的路徑可以指向檔案和/或目錄。

關鍵字引數

  • 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 985
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
fu_clean_components(*comp) 按一下以切換來源
# File lib/fileutils.rb, line 2527
def fu_clean_components(*comp)
  comp.shift while comp.first == "."
  return comp if comp.empty?
  clean = [comp.shift]
  path = File.join(*clean, "") # ending with File::SEPARATOR
  while c = comp.shift
    if c == ".." and clean.last != ".." and !(fu_have_symlink? && File.symlink?(path))
      clean.pop
      path.chomp!(%r((?<=\A|/)[^/]+/\z), "")
    else
      clean << c
      path << c << "/"
    end
  end
  clean
end
fu_split_path(path) 按一下以切換來源
# File lib/fileutils.rb, line 2506
def fu_split_path(path)
  path = File.path(path)
  list = []
  until (parent, base = File.split(path); parent == path or parent == ".")
    list << base
    path = parent
  end
  list << path
  list.reverse!
end
fu_starting_path?(path) 按一下以切換來源
# File lib/fileutils.rb, line 2546
def fu_starting_path?(path)
  path&.start_with?(%r(\w:|/))
end
getwd()
別名:pwd
identical?(a, b)
別名:compare_file
install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil) 按一下以切換來源

複製檔案項目。請參閱 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 指向目錄,則將 src 中的每個路徑 path 複製到 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 1609
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
link_entry(src, dest, dereference_root = false, remove_destination = false) 按一下以切換來源

建立 硬連結;傳回 nil

參數 srcdest可詮釋為路徑

如果 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 812
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
ln(src, dest, force: nil, noop: nil, verbose: nil) 按一下以切換來源

建立 硬連結

參數 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 是現有目錄的路徑時,則對 src 中的每個路徑 target,在 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 516
def ln(src, dest, force: nil, noop: nil, verbose: nil)
  fu_output_message "ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
  return if noop
  fu_each_src_dest0(src, dest) do |s,d|
    remove_file d, true if force
    File.link s, d
  end
end
別名為:link
ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil) 按一下以切換來源

建立符號連結

參數 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 是現有檔案的路徑時,如果且僅當給定關鍵字引數 force: true 時,在 dest 建立符號連結,指向 src(否則會引發例外狀況)

    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 是目錄,則對 src 中的每個子項 child,建立符號連結 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 706
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
別名為:symlink
ln_sf(src, dest, noop: nil, verbose: nil) 按一下以切換來源

類似於FileUtils.ln_s,但總是給定關鍵字引數 force: true

# File lib/fileutils.rb, line 724
def ln_sf(src, dest, noop: nil, verbose: nil)
  ln_s src, dest, force: true, noop: noop, verbose: verbose
end
ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil) 按一下以切換來源

類似於FileUtils.ln_s,但相對於 dest 建立連結。

# File lib/fileutils.rb, line 731
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
makedirs(list, mode: nil, noop: nil, verbose: nil)
別名為:mkdir_p
mkdir(list, mode: nil, noop: nil, verbose: nil) 按一下以切換來源

在給定的 list (單一路徑或路徑陣列) 中的路徑建立目錄;如果它是陣列,傳回 list,否則傳回 [list]

引數 list 或其元素應可 詮釋為路徑

如果沒有關鍵字參數,則透過呼叫 Dir.mkdir(path, mode)list 中的每個 path 建立目錄;請參閱 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 316
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
mkdir_p(list, mode: nil, noop: nil, verbose: nil) 按一下以切換來源

在給定的 list (單一路徑或路徑陣列) 中的路徑建立目錄,並視需要建立祖先目錄;如果它是陣列,傳回 list,否則傳回 [list]

引數 list 或其元素應可 詮釋為路徑

如果沒有關鍵字參數,則透過呼叫 Dir.mkdir(path, mode)list 中的每個 path,以及任何必要的祖先目錄建立目錄;請參閱 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.mkpathFileUtils.makedirsFileUtils.mkdir_p 的別名。

相關:FileUtils.mkdir

# File lib/fileutils.rb, line 365
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
也別名為:mkpathmakedirs
mkpath(list, mode: nil, noop: nil, verbose: nil)
別名為:mkdir_p
move(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
別名:mv
mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil) 按一下以切換來源

移動項目。

參數 src(單一路徑或路徑陣列)和 dest(單一路徑)應 可詮釋為路徑

如果 srcdest 在不同的檔案系統上,則會先複製,然後移除 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(也就是如果 srcdest 在不同的檔案系統上),則忽略引發的 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 1157
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
別名為:move
pwd() 按一下以切換來源

傳回包含目前目錄路徑的字串

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

相關:FileUtils.cd

# File lib/fileutils.rb, line 197
def pwd
  Dir.pwd
end
別名為:getwd
remove(list, force: nil, noop: nil, verbose: nil)
別名為:rm
remove_dir(path, force = false) 按一下以切換來源

遞迴移除 path 給出的目錄項目,它應該是常規檔案、符號連結或目錄的項目。

引數 path可解釋為路徑

選用引數 force 指定是否忽略引發的 StandardError 和其後代的例外狀況。

相關:刪除方法

# File lib/fileutils.rb, line 1492
def remove_dir(path, force = false)
  remove_entry path, force   # FIXME?? check if it is a directory
end
remove_entry(path, force = false) 按一下以切換來源

移除 path 給出的項目,它應該是常規檔案、符號連結或目錄的項目。

引數 path可解釋為路徑

選用引數 force 指定是否忽略引發的 StandardError 和其後代的例外狀況。

相關:FileUtils.remove_entry_secure

# File lib/fileutils.rb, line 1449
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
remove_entry_secure(path, force = false) 按一下以切換來源

安全地移除 path 給出的項目,它應該是常規檔案、符號連結或目錄的項目。

引數 path可解釋為路徑

避免在某些情況下可能存在的本地漏洞;請參閱 避免 TOCTTOU 漏洞

選用引數 force 指定是否忽略引發的 StandardError 和其後代的例外狀況。

相關:刪除方法

# File lib/fileutils.rb, line 1351
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
remove_file(path, force = false) 按一下以切換來源

移除 path 給出的檔案項目,它應該是常規檔案或符號連結的項目。

引數 path可解釋為路徑

選用引數 force 指定是否忽略引發的 StandardError 和其後代的例外狀況。

相關:刪除方法

# File lib/fileutils.rb, line 1473
def remove_file(path, force = false)
  Entry_.new(path).remove_file
rescue
  raise unless force
end
rm(list, force: nil, noop: nil, verbose: nil) 按一下以切換來源

移除給定 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 1216
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
別名為:remove
rm_f(list, noop: nil, verbose: nil) 按一下以切換來源

等於

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

參數 list(單一路徑或路徑陣列)應 可詮釋為路徑

有關關鍵字參數,請參閱 FileUtils.rm

相關:刪除方法

# File lib/fileutils.rb, line 1241
def rm_f(list, noop: nil, verbose: nil)
  rm list, force: true, noop: noop, verbose: verbose
end
別名為:safe_unlink
rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) 按一下以切換來源

移除給定 list(單一路徑或路徑陣列)中路徑的項目;如果 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 1299
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
rm_rf(list, noop: nil, verbose: nil, secure: nil) 按一下以切換來源

等於

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

引數 list 或其元素應可 詮釋為路徑

如果未呼叫關鍵字參數 secure: true,則可能會造成本機漏洞;請參閱 避免 TOCTTOU 漏洞

有關關鍵字參數,請參閱 FileUtils.rm_r

相關:刪除方法

# File lib/fileutils.rb, line 1328
def rm_rf(list, noop: nil, verbose: nil, secure: nil)
  rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
end
別名為:rmtree
rmdir(list, parents: nil, noop: nil, verbose: nil) 按一下以切換來源

移除給定 list(單一路徑或路徑陣列)中路徑的目錄;如果 list 是陣列,則傳回 list,否則傳回 [list]

引數 list 或其元素應可 詮釋為路徑

如果沒有關鍵字參數,則透過呼叫:Dir.rmdir(path) 來移除 list 中每個 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 442
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
rmtree(list, noop: nil, verbose: nil, secure: nil)
別名為:rm_rf
touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil) 按一下以切換來源

更新list(單一路徑或路徑陣列)中路徑所指定條目的修改時間(mtime)和存取時間(atime);如果是陣列,則傳回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 2006
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
uptodate?(new, old_list) 按一下以切換來源

如果路徑new的檔案比陣列old_list中所有路徑的檔案都新,則傳回true;否則傳回false

引數newold_list的元素應可解釋為路徑

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

不存在的檔案視為無限久遠。

相關:FileUtils.touch

# File lib/fileutils.rb, line 264
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