module FileUtils

Namespace for file utility methods for copying, moving, removing, etc.

What’s Here

First, what’s elsewhere. Module FileUtils:

Here, module FileUtils provides methods that are useful for:

Creating

Deleting

Querying

Setting

Comparing

Copying

Moving

Options

Path Arguments

Some methods in FileUtils acceptpath arguments, which are interpreted as paths to filesystem entries:

About the Examples

Some examples here involve trees of file entries. For these, we sometimes display trees using thetree command-line utility, which is a recursive directory-listing utility that produces a depth-indented listing of files and directories.

We use a helper method to launch the command and control the format:

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

To illustrate:

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

Avoiding the TOCTTOU Vulnerability

For certain methods that recursively remove entries, there is a potential vulnerability called theTime-of-check to time-of-use, or TOCTTOU, vulnerability that can exist when:

To avoid that vulnerability, you can use this method to remove entries:

Also available are these methods, each of which calls FileUtils.remove_entry_secure:

Finally, this method for moving entries calls FileUtils.remove_entry_secure if the source and destination are on different file systems (which means that the “move” is really a copy and remove):

Method FileUtils.remove_entry_secure removes securely by applying a special pre-process:

WARNING: You must ensure thatALL parent directories cannot be moved by other untrusted users. For example, parent directories should not be owned by untrusted users, and should not be world writable except when the sticky bit is set.

For details of this security vulnerability, see Perl cases:

Constants

VERSION

The version number.

Public Class Methods

Source
# File lib/fileutils.rb, line 239defcd(dir,verbose:nil,&block)# :yield: dirfu_output_message"cd #{dir}"ifverboseresult =Dir.chdir(dir,&block)fu_output_message'cd -'ifverboseandblockresultend

Changes the working directory to the givendir, which should beinterpretable as a path:

With no block given, changes the current directory to the directory atdir; returns zero:

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

With a block given, changes the current directory to the directory atdir, calls the block with argumentdir, and restores the original current directory; returns the block’s value:

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

Keyword arguments:

  • verbose: true - prints an equivalent command:

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

    Output:

    cd ..cd fileutils

Related:FileUtils.pwd.

Also aliased as:chdir
Alias for:cd
Source
# File lib/fileutils.rb, line 1801defchmod(mode,list,noop:nil,verbose:nil)list =fu_list(list)fu_output_messagesprintf('chmod %s %s',mode_to_s(mode),list.join(' '))ifverbosereturnifnooplist.eachdo|path|Entry_.new(path).chmod(fu_mode(mode,path))endend

Changes permissions on the entries at the paths given inlist (a single path or an array of paths) to the permissions given bymode; returnslist if it is an array,[list] otherwise:

  • Modifies each entry that is a regular file usingFile.chmod.

  • Modifies each entry that is a symbolic link usingFile.lchmod.

Argumentlist or its elements should beinterpretable as paths.

Argumentmode may be either an integer or a string:

  • Integermode: represents the permission bits to be set:

    FileUtils.chmod(0755,'src0.txt')FileUtils.chmod(0644, ['src0.txt','src0.dat'])
  • Stringmode: represents the permissions to be set:

    The string is of the form[targets][[operator][perms[,perms]], where:

    • targets may be any combination of these letters:

      • 'u': permissions apply to the file’s owner.

      • 'g': permissions apply to users in the file’s group.

      • 'o': permissions apply to other users not in the file’s group.

      • 'a' (the default): permissions apply to all users.

    • operator may be one of these letters:

      • '+': adds permissions.

      • '-': removes permissions.

      • '=': sets (replaces) permissions.

    • perms (may be repeated, with separating commas) may be any combination of these letters:

      • 'r': Read.

      • 'w': Write.

      • 'x': Execute (search, for a directory).

      • 'X': Search (for a directories only; must be used with'+')

      • 's': Uid or gid.

      • 't': Sticky bit.

    Examples:

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

Keyword arguments:

  • noop: true - does not change permissions; returnsnil.

  • verbose: true - prints an equivalent command:

    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)

    Output:

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

Related:FileUtils.chmod_R.

Source
# File lib/fileutils.rb, line 1813defchmod_R(mode,list,noop:nil,verbose:nil,force:nil)list =fu_list(list)fu_output_messagesprintf('chmod -R%s %s %s',                            (force?'f':''),mode_to_s(mode),list.join(' '))ifverbosereturnifnooplist.eachdo|root|Entry_.new(root).traversedo|ent|beginent.chmod(fu_mode(mode,ent.path))rescueraiseunlessforceendendendend

LikeFileUtils.chmod, but changes permissions recursively.

Source
# File lib/fileutils.rb, line 1894defchown(user,group,list,noop:nil,verbose:nil)list =fu_list(list)fu_output_messagesprintf('chown %s %s',                            (group?"#{user}:#{group}":user||':'),list.join(' '))ifverbosereturnifnoopuid =fu_get_uid(user)gid =fu_get_gid(group)list.eachdo|path|Entry_.new(path).chownuid,gidendend

Changes the owner and group on the entries at the paths given inlist (a single path or an array of paths) to the givenuser andgroup; returnslist if it is an array,[list] otherwise:

  • Modifies each entry that is a regular file usingFile.chown.

  • Modifies each entry that is a symbolic link usingFile.lchown.

Argumentlist or its elements should beinterpretable as paths.

User and group:

  • Argumentuser may be a user name or a user id; ifnil or-1, the user is not changed.

  • Argumentgroup may be a group name or a group id; ifnil or-1, the group is not changed.

  • The user must be a member of the group.

Examples:

# One path.# User and group as string names.File.stat('src0.txt').uid# => 1004File.stat('src0.txt').gid# => 1004FileUtils.chown('user2','group1','src0.txt')File.stat('src0.txt').uid# => 1006File.stat('src0.txt').gid# => 1005# User and group as uid and gid.FileUtils.chown(1004,1004,'src0.txt')File.stat('src0.txt').uid# => 1004File.stat('src0.txt').gid# => 1004# Array of paths.FileUtils.chown(1006,1005, ['src0.txt','src0.dat'])# Directory (not recursive).FileUtils.chown('user2','group1','.')

Keyword arguments:

  • noop: true - does not change permissions; returnsnil.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    chown user2:group1 src0.txtchown 1004:1004 src0.txtchown 1006:1005 src0.txt src0.datchown user2:group1 src0.txtchown user2:group1 .

Related:FileUtils.chown_R.

Source
# File lib/fileutils.rb, line 1910defchown_R(user,group,list,noop:nil,verbose:nil,force:nil)list =fu_list(list)fu_output_messagesprintf('chown -R%s %s %s',                            (force?'f':''),                            (group?"#{user}:#{group}":user||':'),list.join(' '))ifverbosereturnifnoopuid =fu_get_uid(user)gid =fu_get_gid(group)list.eachdo|root|Entry_.new(root).traversedo|ent|beginent.chownuid,gidrescueraiseunlessforceendendendend

LikeFileUtils.chown, but changes owner and group recursively.

Alias for:compare_file
Source
# File lib/fileutils.rb, line 2616defself.collect_method(opt)OPT_TABLE.keys.select {|m|OPT_TABLE[m].include?(opt) }end

Returns an array of the string method names of the methods that accept the given keyword optionopt; the argument must be a symbol:

FileUtils.collect_method(:preserve)# => ["cp", "copy", "cp_r", "install"]
Source
# File lib/fileutils.rb, line 2577defself.commandsOPT_TABLE.keysend

Returns an array of the string names of FileUtils methods that accept one or more keyword arguments:

FileUtils.commands.sort.take(3)# => ["cd", "chdir", "chmod"]
Source
# File lib/fileutils.rb, line 1505defcompare_file(a,b)returnfalseunlessFile.size(a)==File.size(b)File.open(a,'rb') {|fa|File.open(b,'rb') {|fb|returncompare_stream(fa,fb)    }  }end

Returnstrue if the contents of filesa andb are identical,false otherwise.

Argumentsa andb should beinterpretable as a path.

FileUtils.identical? andFileUtils.cmp are aliases forFileUtils.compare_file.

Related:FileUtils.compare_stream.

Also aliased as:identical?,cmp
Source
# File lib/fileutils.rb, line 1528defcompare_stream(a,b)bsize =fu_stream_blksize(a,b)sa =String.new(capacity:bsize)sb =String.new(capacity:bsize)begina.read(bsize,sa)b.read(bsize,sb)returntrueifsa.empty?&&sb.empty?endwhilesa==sbfalseend

Returnstrue if the contents of streamsa andb are identical,false otherwise.

Argumentsa andb should beinterpretable as a path.

Related:FileUtils.compare_file.

Alias for:cp
Source
# File lib/fileutils.rb, line 1037defcopy_entry(src,dest,preserve =false,dereference_root =false,remove_destination =false)ifdereference_rootsrc =File.realpath(src)endEntry_.new(src,nil,false).wrap_traverse(procdo|ent|destent =Entry_.new(dest,ent.rel,false)File.unlinkdestent.pathifremove_destination&& (File.file?(destent.path)||File.symlink?(destent.path))ent.copydestent.pathend,procdo|ent|destent =Entry_.new(dest,ent.rel,false)ent.copy_metadatadestent.pathifpreserveend)end

Recursively copies files fromsrc todest.

Argumentssrc anddest should beinterpretable as paths.

Ifsrc is the path to a file, copiessrc todest:

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

Ifsrc is a directory, recursively copiessrc todest:

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

The recursive copying preserves file types for regular files, directories, and symbolic links; other file types (FIFO streams, device files, etc.) are not supported.

Optional arguments:

  • dereference_root - ifsrc is a symbolic link, follows the link (false by default).

  • preserve - preserves file times (false by default).

  • remove_destination - removesdest before copying files (false by default).

Related:methods for copying.

Source
# File lib/fileutils.rb, line 1073defcopy_file(src,dest,preserve =false,dereference =true)ent =Entry_.new(src,nil,dereference)ent.copy_filedestent.copy_metadatadestifpreserveend

Copies file fromsrc todest, which should not be directories.

Argumentssrc anddest should beinterpretable as paths.

Examples:

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

Optional arguments:

  • dereference - ifsrc is a symbolic link, follows the link (true by default).

  • preserve - preserves file times (false by default).

  • remove_destination - removesdest before copying files (false by default).

Related:methods for copying.

Source
# File lib/fileutils.rb, line 1085defcopy_stream(src,dest)IO.copy_stream(src,dest)end

Copies IO streamsrc to IO streamdest viaIO.copy_stream.

Related:methods for copying.

Source
# File lib/fileutils.rb, line 870defcp(src,dest,preserve:nil,noop:nil,verbose:nil)fu_output_message"cp#{preserve ? ' -p' : ''} #{[src,dest].flatten.join ' '}"ifverbosereturnifnoopfu_each_src_dest(src,dest)do|s,d|copy_files,d,preserveendend

Copies files.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Ifsrc is the path to a file anddest is not the path to a directory, copiessrc todest:

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

Ifsrc is the path to a file anddest is the path to a directory, copiessrc todest/src:

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

Ifsrc is an array of paths to files anddest is the path to a directory, copies from eachsrc todest:

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')# => trueFile.file?('dest2/src2.dat')# => true

Keyword arguments:

  • preserve: true - preserves file times.

  • noop: true - does not copy files.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    cpsrc0.txtdest0.txtcpsrc1.txtdest1cpsrc2.txtsrc2.datdest2

Raises an exception ifsrc is a directory.

Related:methods for copying.

Also aliased as:copy
Source
# File lib/fileutils.rb, line 628defcp_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 ' '}"ifverbosereturnifnoopfu_each_src_dest(src,dest)do|s,d|link_entrys,d,dereference_root,remove_destinationendend

Createshard links.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Ifsrc is the path to a directory anddest does not exist, creates linksdest and descendents pointing tosrc and its descendents:

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

Ifsrc anddest are both paths to directories, creates linksdest/src and descendents pointing tosrc and its descendents:

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

Ifsrc is an array of paths to entries anddest is the path to a directory, for each pathfilepath insrc, creates a link atdest/filepath pointing to that path:

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

Keyword arguments:

  • dereference_root: false - ifsrc is a symbolic link, does not dereference it.

  • noop: true - does not create links.

  • remove_destination: true - removesdest before creating links.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    cp -lr src0 dest0cp -lr src1 dest1cp -lr src2/sub0 src2/sub1 dest2

Raises an exception ifdest is the path to an existing file or directory and keyword argumentremove_destination: true is not given.

Related:methods for copying.

Source
# File lib/fileutils.rb, line 982defcp_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 ' '}"ifverbosereturnifnoopfu_each_src_dest(src,dest)do|s,d|copy_entrys,d,preserve,dereference_root,remove_destinationendend

Recursively copies files.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

The mode, owner, and group are retained in the copy; to change those, useFileUtils.install instead.

Ifsrc is the path to a file anddest is not the path to a directory, copiessrc todest:

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

Ifsrc is the path to a file anddest is the path to a directory, copiessrc todest/src:

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

Ifsrc is the path to a directory anddest does not exist, recursively copiessrc todest:

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

Ifsrc anddest are paths to directories, recursively copiessrc todest/src:

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

Ifsrc is an array of paths anddest is a directory, recursively copies from each path insrc todest; the paths insrc may point to files and/or directories.

Keyword arguments:

  • dereference_root: false - ifsrc is a symbolic link, does not dereference it.

  • noop: true - does not copy files.

  • preserve: true - preserves file times.

  • remove_destination: true - removesdest before copying files.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    cp -r src0.txt dest0.txtcp -r src1.txt dest1cp -r src2 dest2cp -r src3 dest3

Raises an exception ofsrc is the path to a directory anddest is the path to a file.

Related:methods for copying.

Alias for:pwd
Source
# File lib/fileutils.rb, line 2595defself.have_option?(mid,opt)li =OPT_TABLE[mid.to_s]orraiseArgumentError,"no such method: #{mid}"li.include?(opt)end

Returnstrue if methodmid accepts the given optionopt,false otherwise; the arguments may be strings or symbols:

FileUtils.have_option?(:chmod,:noop)# => trueFileUtils.have_option?('chmod','secure')# => false
Alias for:compare_file
Source
# File lib/fileutils.rb, line 1607definstall(src,dest,mode:nil,owner:nil,group:nil,preserve:nil,noop:nil,verbose:nil)ifverbosemsg =+"install -c"msg<<' -p'ifpreservemsg<<' -m '<<mode_to_s(mode)ifmodemsg<<" -o #{owner}"ifownermsg<<" -g #{group}"ifgroupmsg<<' '<< [src,dest].flatten.join(' ')fu_output_messagemsgendreturnifnoopuid =fu_get_uid(owner)gid =fu_get_gid(group)fu_each_src_dest(src,dest)do|s,d|st =File.stat(s)unlessFile.exist?(d)andcompare_file(s,d)remove_filed,trueifd.end_with?('/')mkdir_pdcopy_files,d+File.basename(s)elsemkdir_pFile.expand_path('..',d)copy_files,dendFile.utimest.atime,st.mtime,difpreserveFile.chmodfu_mode(mode,st),difmodeFile.chownuid,gid,difuidorgidendendend

Copies a file entry. Seeinstall(1).

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths;

If the entry atdest does not exist, copies fromsrc todest:

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

Ifdest is a file entry, copies fromsrc todest, overwriting:

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

Ifdest is a directory entry, copies fromsrc todest/src, overwriting if necessary:

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"

Ifsrc is an array of paths anddest points to a directory, copies each pathpath insrc todest/path:

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

Keyword arguments:

  • group:group - changes the group if notnil, usingFile.chown.

  • mode:permissions - changes the permissions. usingFile.chmod.

  • noop: true - does not copy entries; returnsnil.

  • owner:owner - changes the owner if notnil, usingFile.chown.

  • preserve: true - preserve timestamps usingFile.utime.

  • verbose: true - prints an equivalent command:

    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)

    Output:

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

Related:methods for copying.

Alias for:ln
Source
# File lib/fileutils.rb, line 809deflink_entry(src,dest,dereference_root =false,remove_destination =false)Entry_.new(src,nil,dereference_root).traversedo|ent|destent =Entry_.new(dest,ent.rel,false)File.unlinkdestent.pathifremove_destination&&File.file?(destent.path)ent.linkdestent.pathendend

Createshard links; returnsnil.

Argumentssrc anddest should beinterpretable as paths.

Ifsrc is the path to a file anddest does not exist, creates a hard link atdest pointing tosrc:

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

Ifsrc is the path to a directory anddest does not exist, recursively creates hard links atdest pointing to paths insrc:

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')# => trueFileUtils.link_entry('src1','dest1')File.file?('dest1/dir0/t0.txt')# => trueFile.file?('dest1/dir0/t1.txt')# => trueFile.file?('dest1/dir1/t2.txt')# => trueFile.file?('dest1/dir1/t3.txt')# => true

Optional arguments:

  • dereference_root - dereferencessrc if it is a symbolic link (false by default).

  • remove_destination - removesdest before creating links (false by default).

Raises an exception ifdest is the path to an existing file or directory and optional argumentremove_destination is not given.

Related:FileUtils.ln (has different options).

Source
# File lib/fileutils.rb, line 517defln(src,dest,force:nil,noop:nil,verbose:nil)fu_output_message"ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}"ifverbosereturnifnoopfu_each_src_dest0(src,dest)do|s,d|remove_filed,trueifforceFile.links,dendend

Createshard links.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Whensrc is the path to an existing file anddest is the path to a non-existent file, creates a hard link atdest pointing tosrc; returns zero:

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

Whensrc is the path to an existing file anddest is the path to an existing directory, creates a hard link atdest/src pointing tosrc; returns zero:

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

Whensrc is an array of paths to existing files anddest is the path to an existing directory, then for each pathtarget insrc, creates a hard link atdest/target pointing totarget; returnssrc:

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"]

Keyword arguments:

  • force: true - overwritesdest if it exists.

  • noop: true - does not create links.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    ln tmp0/t.txt tmp1/t.lnkln tmp2/t.dat tmp3ln tmp0/t.txt tmp2/t.dat tmp4/

Raises an exception ifdest is the path to an existing file and keyword argumentforce is nottrue.

Related:FileUtils.link_entry (has different options).

Also aliased as:link
Source
# File lib/fileutils.rb, line 707defln_s(src,dest,force:nil,relative:false,target_directory:true,noop:nil,verbose:nil)ifrelativereturnln_sr(src,dest,force:force,target_directory:target_directory,noop:noop,verbose:verbose)endfu_output_message"ln -s#{force ? 'f' : ''}#{    target_directory ? '' : 'T'} #{[src,dest].flatten.join ' '}"ifverbosereturnifnoopfu_each_src_dest0(src,dest,target_directory)do|s,d|remove_filed,trueifforceFile.symlinks,dendend

Createssymbolic links.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Ifsrc is the path to an existing file:

  • Whendest is the path to a non-existent file, creates a symbolic link atdest pointing tosrc:

    FileUtils.touch('src0.txt')File.exist?('dest0.txt')# => falseFileUtils.ln_s('src0.txt','dest0.txt')File.symlink?('dest0.txt')# => true
  • Whendest is the path to an existing file, creates a symbolic link atdest pointing tosrc if and only if keyword argumentforce: true is given (raises an exception otherwise):

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

Ifdest is the path to a directory, creates a symbolic link atdest/src pointing tosrc:

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

Ifsrc is an array of paths to existing files anddest is a directory, for each childchild insrc creates a symbolic linkdest/child pointing tochild:

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')# => trueFile.symlink?('destdir3/src1.txt')# => true

Keyword arguments:

  • force: true - overwritesdest if it exists.

  • relative: false - create links relative todest.

  • noop: true - does not create links.

  • verbose: true - prints an equivalent command:

    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)

    Output:

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

Related:FileUtils.ln_sf.

Also aliased as:symlink
Source
# File lib/fileutils.rb, line 726defln_sf(src,dest,noop:nil,verbose:nil)ln_ssrc,dest,force:true,noop:noop,verbose:verboseend

LikeFileUtils.ln_s, but always with keyword argumentforce: true given.

Source
# File lib/fileutils.rb, line 733defln_sr(src,dest,target_directory:true,force:nil,noop:nil,verbose:nil)cmd ="ln -s#{force ? 'f' : ''}#{target_directory ? '' : 'T'}"ifverbosefu_each_src_dest0(src,dest,target_directory)do|s,d|iftarget_directoryparent =File.dirname(d)destdirs =fu_split_path(parent)real_ddirs =fu_split_path(File.realpath(parent))elsedestdirs||=fu_split_path(dest)real_ddirs||=fu_split_path(File.realdirpath(dest))endsrcdirs =fu_split_path(s)i =fu_common_components(srcdirs,destdirs)n =destdirs.size-in-=1unlesstarget_directorylink1 =fu_clean_components(*Array.new([n,0].max,'..'),*srcdirs[i..-1])beginreal_sdirs =fu_split_path(File.realdirpath(s))rescuenilrescueelsei =fu_common_components(real_sdirs,real_ddirs)n =real_ddirs.size-in-=1unlesstarget_directorylink2 =fu_clean_components(*Array.new([n,0].max,'..'),*real_sdirs[i..-1])link1 =link2iflink1.size>link2.sizeends =File.join(link1)fu_output_message [cmd,s,d].flatten.join(' ')ifverbosenextifnoopremove_filed,trueifforceFile.symlinks,dendend

LikeFileUtils.ln_s, but create links relative todest.

Alias for:mkdir_p
Source
# File lib/fileutils.rb, line 317defmkdir(list,mode:nil,noop:nil,verbose:nil)list =fu_list(list)fu_output_message"mkdir #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}"ifverbosereturnifnooplist.eachdo|dir|fu_mkdirdir,modeendend

Creates directories at the paths in the givenlist (a single path or an array of paths); returnslist if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

With no keyword arguments, creates a directory at eachpath inlist by calling:Dir.mkdir(path, mode); seeDir.mkdir:

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

Keyword arguments:

  • mode:mode - also callsFile.chmod(mode, path); seeFile.chmod.

  • noop: true - does not create directories.

  • verbose: true - prints an equivalent command:

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

    Output:

    mkdir tmp0 tmp1mkdir -m 700 tmp2 tmp3

Raises an exception if any path points to an existing file or directory, or if for any reason a directory cannot be created.

Related:FileUtils.mkdir_p.

Source
# File lib/fileutils.rb, line 366defmkdir_p(list,mode:nil,noop:nil,verbose:nil)list =fu_list(list)fu_output_message"mkdir -p #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}"ifverbosereturn*listifnooplist.eachdo|item|path =remove_trailing_slash(item)stack = []untilFile.directory?(path)||File.dirname(path)==pathstack.pushpathpath =File.dirname(path)endstack.reverse_eachdo|dir|beginfu_mkdirdir,moderescueSystemCallErrorraiseunlessFile.directory?(dir)endendendreturn*listend

Creates directories at the paths in the givenlist (a single path or an array of paths), also creating ancestor directories as needed; returnslist if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

With no keyword arguments, creates a directory at eachpath inlist, along with any needed ancestor directories, by calling:Dir.mkdir(path, mode); seeDir.mkdir:

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

Keyword arguments:

  • mode:mode - also callsFile.chmod(mode, path); seeFile.chmod.

  • noop: true - does not create directories.

  • verbose: true - prints an equivalent command:

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

    Output:

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

Raises an exception if for any reason a directory cannot be created.

FileUtils.mkpath andFileUtils.makedirs are aliases forFileUtils.mkdir_p.

Related:FileUtils.mkdir.

Also aliased as:mkpath,makedirs
Alias for:mkdir_p
Alias for:mv
Source
# File lib/fileutils.rb, line 1154defmv(src,dest,force:nil,noop:nil,verbose:nil,secure:nil)fu_output_message"mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}"ifverbosereturnifnoopfu_each_src_dest(src,dest)do|s,d|destent =Entry_.new(d,nil,true)beginifdestent.exist?ifdestent.directory?raiseErrno::EEXIST,dendendbeginFile.renames,drescueErrno::EXDEV,Errno::EPERM# move from unencrypted to encrypted dir (ext4)copy_entrys,d,trueifsecureremove_entry_secures,forceelseremove_entrys,forceendendrescueSystemCallErrorraiseunlessforceendendend

Moves entries.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Ifsrc anddest are on different file systems, first copies, then removessrc.

May cause a local vulnerability if not called with keyword argumentsecure: true; seeAvoiding the TOCTTOU Vulnerability.

Ifsrc is the path to a single file or directory anddest does not exist, movessrc todest:

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

Ifsrc is an array of paths to files and directories anddest is the path to a directory, copies from each path in the array todest:

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

Keyword arguments:

  • force: true - if the move includes removingsrc (that is, ifsrc anddest are on different file systems), ignores raised exceptions ofStandardError and its descendants.

  • noop: true - does not move files.

  • secure: true - removessrc securely; see details atFileUtils.remove_entry_secure.

  • verbose: true - prints an equivalent command:

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

    Output:

    mvsrc0dest0mvsrc1.txtsrc1dest1
Also aliased as:move
Source
# File lib/fileutils.rb, line 2585defself.optionsOPT_TABLE.values.flatten.uniq.map {|sym|sym.to_s }end

Returns an array of the string keyword names:

FileUtils.options.take(3)# => ["noop", "verbose", "force"]
Source
# File lib/fileutils.rb, line 2606defself.options_of(mid)OPT_TABLE[mid.to_s].map {|sym|sym.to_s }end

Returns an array of the string keyword name for methodmid; the argument may be a string or a symbol:

FileUtils.options_of(:rm)# => ["force", "noop", "verbose"]FileUtils.options_of('mv')# => ["force", "noop", "verbose", "secure"]
Source
# File lib/fileutils.rb, line 198defpwdDir.pwdend

Returns a string containing the path to the current directory:

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

Related:FileUtils.cd.

Also aliased as:getwd
Alias for:rm
Source
# File lib/fileutils.rb, line 1489defremove_dir(path,force =false)raiseErrno::ENOTDIR,pathunlessforceorFile.directory?(path)remove_entrypath,forceend

Recursively removes the directory entry given bypath, which should be the entry for a regular file, a symbolic link, or a directory.

Argumentpath should beinterpretable as a path.

Optional argumentforce specifies whether to ignore raised exceptions ofStandardError and its descendants.

Related:methods for deleting.

Source
# File lib/fileutils.rb, line 1446defremove_entry(path,force =false)Entry_.new(path).postorder_traversedo|ent|beginent.removerescueraiseunlessforceendendrescueraiseunlessforceend

Removes the entry given bypath, which should be the entry for a regular file, a symbolic link, or a directory.

Argumentpath should beinterpretable as a path.

Optional argumentforce specifies whether to ignore raised exceptions ofStandardError and its descendants.

Related:FileUtils.remove_entry_secure.

Source
# File lib/fileutils.rb, line 1348defremove_entry_secure(path,force =false)unlessfu_have_symlink?remove_entrypath,forcereturnendfullpath =File.expand_path(path)st =File.lstat(fullpath)unlessst.directory?File.unlinkfullpathreturnend# is a directory.parent_st =File.stat(File.dirname(fullpath))unlessparent_st.world_writable?remove_entrypath,forcereturnendunlessparent_st.sticky?raiseArgumentError,"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 rooteuid =Process.euiddot_file =fullpath+"/."beginFile.open(dot_file) {|f|unlessfu_stat_identical_entry?(st,f.stat)# symlink (TOC-to-TOU attack?)File.unlinkfullpathreturnendf.chowneuid,-1f.chmod0700    }rescueErrno::EISDIR# JRuby in non-native mode can't open files as dirsFile.lstat(dot_file).tap {|fstat|unlessfu_stat_identical_entry?(st,fstat)# symlink (TOC-to-TOU attack?)File.unlinkfullpathreturnendFile.chowneuid,-1,dot_fileFile.chmod0700,dot_file    }endunlessfu_stat_identical_entry?(st,File.lstat(fullpath))# TOC-to-TOU attack?File.unlinkfullpathreturnend# ---- tree root is frozen ----root =Entry_.new(path)root.preorder_traversedo|ent|ifent.directory?ent.chowneuid,-1ent.chmod0700endendroot.postorder_traversedo|ent|beginent.removerescueraiseunlessforceendendrescueraiseunlessforceend

Securely removes the entry given bypath, which should be the entry for a regular file, a symbolic link, or a directory.

Argumentpath should beinterpretable as a path.

Avoids a local vulnerability that can exist in certain circumstances; seeAvoiding the TOCTTOU Vulnerability.

Optional argumentforce specifies whether to ignore raised exceptions ofStandardError and its descendants.

Related:methods for deleting.

Source
# File lib/fileutils.rb, line 1470defremove_file(path,force =false)Entry_.new(path).remove_filerescueraiseunlessforceend

Removes the file entry given bypath, which should be the entry for a regular file or a symbolic link.

Argumentpath should beinterpretable as a path.

Optional argumentforce specifies whether to ignore raised exceptions ofStandardError and its descendants.

Related:methods for deleting.

Source
# File lib/fileutils.rb, line 1213defrm(list,force:nil,noop:nil,verbose:nil)list =fu_list(list)fu_output_message"rm#{force ? ' -f' : ''} #{list.join ' '}"ifverbosereturnifnooplist.eachdo|path|remove_filepath,forceendend

Removes entries at the paths in the givenlist (a single path or an array of paths) returnslist, if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

With no keyword arguments, removes files at the paths given inlist:

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

Keyword arguments:

  • force: true - ignores raised exceptions ofStandardError and its descendants.

  • noop: true - does not remove files; returnsnil.

  • verbose: true - prints an equivalent command:

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

    Output:

    rmsrc0.datsrc0.txt

Related:methods for deleting.

Also aliased as:remove
Source
# File lib/fileutils.rb, line 1238defrm_f(list,noop:nil,verbose:nil)rmlist,force:true,noop:noop,verbose:verboseend

Equivalent to:

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

Argumentlist (a single path or an array of paths) should beinterpretable as paths.

SeeFileUtils.rm for keyword arguments.

Related:methods for deleting.

Also aliased as:safe_unlink
Source
# File lib/fileutils.rb, line 1296defrm_r(list,force:nil,noop:nil,verbose:nil,secure:nil)list =fu_list(list)fu_output_message"rm -r#{force ? 'f' : ''} #{list.join ' '}"ifverbosereturnifnooplist.eachdo|path|ifsecureremove_entry_securepath,forceelseremove_entrypath,forceendendend

Removes entries at the paths in the givenlist (a single path or an array of paths); returnslist, if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

May cause a local vulnerability if not called with keyword argumentsecure: true; seeAvoiding the TOCTTOU Vulnerability.

For each file path, removes the file at that path:

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

For each directory path, recursively removes files and directories:

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

Keyword arguments:

  • force: true - ignores raised exceptions ofStandardError and its descendants.

  • noop: true - does not remove entries; returnsnil.

  • secure: true - removessrc securely; see details atFileUtils.remove_entry_secure.

  • verbose: true - prints an equivalent command:

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

    Output:

    rm -r src0.dat src0.txtrm -r src1

Related:methods for deleting.

Source
# File lib/fileutils.rb, line 1325defrm_rf(list,noop:nil,verbose:nil,secure:nil)rm_rlist,force:true,noop:noop,verbose:verbose,secure:secureend

Equivalent to:

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

Argumentlist or its elements should beinterpretable as paths.

May cause a local vulnerability if not called with keyword argumentsecure: true; seeAvoiding the TOCTTOU Vulnerability.

SeeFileUtils.rm_r for keyword arguments.

Related:methods for deleting.

Also aliased as:rmtree
Source
# File lib/fileutils.rb, line 443defrmdir(list,parents:nil,noop:nil,verbose:nil)list =fu_list(list)fu_output_message"rmdir #{parents ? '-p ' : ''}#{list.join ' '}"ifverbosereturnifnooplist.eachdo|dir|Dir.rmdir(dir =remove_trailing_slash(dir))ifparentsbeginuntil (parent =File.dirname(dir))=='.'orparent==dirdir =parentDir.rmdir(dir)endrescueErrno::ENOTEMPTY,Errno::EEXIST,Errno::ENOENTendendendend

Removes directories at the paths in the givenlist (a single path or an array of paths); returnslist, if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

With no keyword arguments, removes the directory at eachpath inlist, by calling:Dir.rmdir(path); seeDir.rmdir:

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

Keyword arguments:

  • parents: true - removes successive ancestor directories if empty.

  • noop: true - does not remove directories.

  • verbose: true - prints an equivalent command:

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

    Output:

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

Raises an exception if a directory does not exist or if for any reason a directory cannot be removed.

Related:methods for deleting.

Alias for:rm_rf
Alias for:rm_f
Alias for:ln_s
Source
# File lib/fileutils.rb, line 2004deftouch(list,noop:nil,verbose:nil,mtime:nil,nocreate:nil)list =fu_list(list)t =mtimeifverbosefu_output_message"touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}"endreturnifnooplist.eachdo|path|created =nocreatebeginFile.utime(t,t,path)rescueErrno::ENOENTraiseifcreatedFile.open(path,'a') {        ;      }created =trueretryiftendendend

Updates modification times (mtime) and access times (atime) of the entries given by the paths inlist (a single path or an array of paths); returnslist if it is an array,[list] otherwise.

By default, creates an empty file for any path to a non-existent entry; use keyword argumentnocreate to raise an exception instead.

Argumentlist or its elements should beinterpretable as paths.

Examples:

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

Keyword arguments:

  • mtime:time - sets the entry’s mtime to the given time, instead of the current time.

  • nocreate: true - raises an exception if the entry does not exist.

  • noop: true - does not touch entries; returnsnil.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    touchsrc0.txttouchsrc0.txtsrc0.dattouchsrc0.txt

Related:FileUtils.uptodate?.

Source
# File lib/fileutils.rb, line 265defuptodate?(new,old_list)returnfalseunlessFile.exist?(new)new_time =File.mtime(new)old_list.eachdo|old|ifFile.exist?(old)returnfalseunlessnew_time>File.mtime(old)endendtrueend

Returnstrue if the file at pathnew is newer than all the files at paths in arrayold_list;false otherwise.

Argumentnew and the elements ofold_list should beinterpretable as paths:

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

A non-existent file is considered to be infinitely old.

Related:FileUtils.touch.

Private Instance Methods

Source
# File lib/fileutils.rb, line 239defcd(dir,verbose:nil,&block)# :yield: dirfu_output_message"cd #{dir}"ifverboseresult =Dir.chdir(dir,&block)fu_output_message'cd -'ifverboseandblockresultend

Changes the working directory to the givendir, which should beinterpretable as a path:

With no block given, changes the current directory to the directory atdir; returns zero:

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

With a block given, changes the current directory to the directory atdir, calls the block with argumentdir, and restores the original current directory; returns the block’s value:

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

Keyword arguments:

  • verbose: true - prints an equivalent command:

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

    Output:

    cd ..cd fileutils

Related:FileUtils.pwd.

Also aliased as:chdir
Alias for:cd
Source
# File lib/fileutils.rb, line 1801defchmod(mode,list,noop:nil,verbose:nil)list =fu_list(list)fu_output_messagesprintf('chmod %s %s',mode_to_s(mode),list.join(' '))ifverbosereturnifnooplist.eachdo|path|Entry_.new(path).chmod(fu_mode(mode,path))endend

Changes permissions on the entries at the paths given inlist (a single path or an array of paths) to the permissions given bymode; returnslist if it is an array,[list] otherwise:

  • Modifies each entry that is a regular file usingFile.chmod.

  • Modifies each entry that is a symbolic link usingFile.lchmod.

Argumentlist or its elements should beinterpretable as paths.

Argumentmode may be either an integer or a string:

  • Integermode: represents the permission bits to be set:

    FileUtils.chmod(0755,'src0.txt')FileUtils.chmod(0644, ['src0.txt','src0.dat'])
  • Stringmode: represents the permissions to be set:

    The string is of the form[targets][[operator][perms[,perms]], where:

    • targets may be any combination of these letters:

      • 'u': permissions apply to the file’s owner.

      • 'g': permissions apply to users in the file’s group.

      • 'o': permissions apply to other users not in the file’s group.

      • 'a' (the default): permissions apply to all users.

    • operator may be one of these letters:

      • '+': adds permissions.

      • '-': removes permissions.

      • '=': sets (replaces) permissions.

    • perms (may be repeated, with separating commas) may be any combination of these letters:

      • 'r': Read.

      • 'w': Write.

      • 'x': Execute (search, for a directory).

      • 'X': Search (for a directories only; must be used with'+')

      • 's': Uid or gid.

      • 't': Sticky bit.

    Examples:

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

Keyword arguments:

  • noop: true - does not change permissions; returnsnil.

  • verbose: true - prints an equivalent command:

    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)

    Output:

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

Related:FileUtils.chmod_R.

Source
# File lib/fileutils.rb, line 1813defchmod_R(mode,list,noop:nil,verbose:nil,force:nil)list =fu_list(list)fu_output_messagesprintf('chmod -R%s %s %s',                            (force?'f':''),mode_to_s(mode),list.join(' '))ifverbosereturnifnooplist.eachdo|root|Entry_.new(root).traversedo|ent|beginent.chmod(fu_mode(mode,ent.path))rescueraiseunlessforceendendendend

LikeFileUtils.chmod, but changes permissions recursively.

Source
# File lib/fileutils.rb, line 1894defchown(user,group,list,noop:nil,verbose:nil)list =fu_list(list)fu_output_messagesprintf('chown %s %s',                            (group?"#{user}:#{group}":user||':'),list.join(' '))ifverbosereturnifnoopuid =fu_get_uid(user)gid =fu_get_gid(group)list.eachdo|path|Entry_.new(path).chownuid,gidendend

Changes the owner and group on the entries at the paths given inlist (a single path or an array of paths) to the givenuser andgroup; returnslist if it is an array,[list] otherwise:

  • Modifies each entry that is a regular file usingFile.chown.

  • Modifies each entry that is a symbolic link usingFile.lchown.

Argumentlist or its elements should beinterpretable as paths.

User and group:

  • Argumentuser may be a user name or a user id; ifnil or-1, the user is not changed.

  • Argumentgroup may be a group name or a group id; ifnil or-1, the group is not changed.

  • The user must be a member of the group.

Examples:

# One path.# User and group as string names.File.stat('src0.txt').uid# => 1004File.stat('src0.txt').gid# => 1004FileUtils.chown('user2','group1','src0.txt')File.stat('src0.txt').uid# => 1006File.stat('src0.txt').gid# => 1005# User and group as uid and gid.FileUtils.chown(1004,1004,'src0.txt')File.stat('src0.txt').uid# => 1004File.stat('src0.txt').gid# => 1004# Array of paths.FileUtils.chown(1006,1005, ['src0.txt','src0.dat'])# Directory (not recursive).FileUtils.chown('user2','group1','.')

Keyword arguments:

  • noop: true - does not change permissions; returnsnil.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    chown user2:group1 src0.txtchown 1004:1004 src0.txtchown 1006:1005 src0.txt src0.datchown user2:group1 src0.txtchown user2:group1 .

Related:FileUtils.chown_R.

Source
# File lib/fileutils.rb, line 1910defchown_R(user,group,list,noop:nil,verbose:nil,force:nil)list =fu_list(list)fu_output_messagesprintf('chown -R%s %s %s',                            (force?'f':''),                            (group?"#{user}:#{group}":user||':'),list.join(' '))ifverbosereturnifnoopuid =fu_get_uid(user)gid =fu_get_gid(group)list.eachdo|root|Entry_.new(root).traversedo|ent|beginent.chownuid,gidrescueraiseunlessforceendendendend

LikeFileUtils.chown, but changes owner and group recursively.

Alias for:compare_file
Source
# File lib/fileutils.rb, line 1505defcompare_file(a,b)returnfalseunlessFile.size(a)==File.size(b)File.open(a,'rb') {|fa|File.open(b,'rb') {|fb|returncompare_stream(fa,fb)    }  }end

Returnstrue if the contents of filesa andb are identical,false otherwise.

Argumentsa andb should beinterpretable as a path.

FileUtils.identical? andFileUtils.cmp are aliases forFileUtils.compare_file.

Related:FileUtils.compare_stream.

Also aliased as:identical?,cmp
Source
# File lib/fileutils.rb, line 1528defcompare_stream(a,b)bsize =fu_stream_blksize(a,b)sa =String.new(capacity:bsize)sb =String.new(capacity:bsize)begina.read(bsize,sa)b.read(bsize,sb)returntrueifsa.empty?&&sb.empty?endwhilesa==sbfalseend

Returnstrue if the contents of streamsa andb are identical,false otherwise.

Argumentsa andb should beinterpretable as a path.

Related:FileUtils.compare_file.

Alias for:cp
Source
# File lib/fileutils.rb, line 1037defcopy_entry(src,dest,preserve =false,dereference_root =false,remove_destination =false)ifdereference_rootsrc =File.realpath(src)endEntry_.new(src,nil,false).wrap_traverse(procdo|ent|destent =Entry_.new(dest,ent.rel,false)File.unlinkdestent.pathifremove_destination&& (File.file?(destent.path)||File.symlink?(destent.path))ent.copydestent.pathend,procdo|ent|destent =Entry_.new(dest,ent.rel,false)ent.copy_metadatadestent.pathifpreserveend)end

Recursively copies files fromsrc todest.

Argumentssrc anddest should beinterpretable as paths.

Ifsrc is the path to a file, copiessrc todest:

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

Ifsrc is a directory, recursively copiessrc todest:

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

The recursive copying preserves file types for regular files, directories, and symbolic links; other file types (FIFO streams, device files, etc.) are not supported.

Optional arguments:

  • dereference_root - ifsrc is a symbolic link, follows the link (false by default).

  • preserve - preserves file times (false by default).

  • remove_destination - removesdest before copying files (false by default).

Related:methods for copying.

Source
# File lib/fileutils.rb, line 1073defcopy_file(src,dest,preserve =false,dereference =true)ent =Entry_.new(src,nil,dereference)ent.copy_filedestent.copy_metadatadestifpreserveend

Copies file fromsrc todest, which should not be directories.

Argumentssrc anddest should beinterpretable as paths.

Examples:

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

Optional arguments:

  • dereference - ifsrc is a symbolic link, follows the link (true by default).

  • preserve - preserves file times (false by default).

  • remove_destination - removesdest before copying files (false by default).

Related:methods for copying.

Source
# File lib/fileutils.rb, line 1085defcopy_stream(src,dest)IO.copy_stream(src,dest)end

Copies IO streamsrc to IO streamdest viaIO.copy_stream.

Related:methods for copying.

Source
# File lib/fileutils.rb, line 870defcp(src,dest,preserve:nil,noop:nil,verbose:nil)fu_output_message"cp#{preserve ? ' -p' : ''} #{[src,dest].flatten.join ' '}"ifverbosereturnifnoopfu_each_src_dest(src,dest)do|s,d|copy_files,d,preserveendend

Copies files.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Ifsrc is the path to a file anddest is not the path to a directory, copiessrc todest:

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

Ifsrc is the path to a file anddest is the path to a directory, copiessrc todest/src:

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

Ifsrc is an array of paths to files anddest is the path to a directory, copies from eachsrc todest:

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')# => trueFile.file?('dest2/src2.dat')# => true

Keyword arguments:

  • preserve: true - preserves file times.

  • noop: true - does not copy files.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    cpsrc0.txtdest0.txtcpsrc1.txtdest1cpsrc2.txtsrc2.datdest2

Raises an exception ifsrc is a directory.

Related:methods for copying.

Also aliased as:copy
Source
# File lib/fileutils.rb, line 628defcp_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 ' '}"ifverbosereturnifnoopfu_each_src_dest(src,dest)do|s,d|link_entrys,d,dereference_root,remove_destinationendend

Createshard links.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Ifsrc is the path to a directory anddest does not exist, creates linksdest and descendents pointing tosrc and its descendents:

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

Ifsrc anddest are both paths to directories, creates linksdest/src and descendents pointing tosrc and its descendents:

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

Ifsrc is an array of paths to entries anddest is the path to a directory, for each pathfilepath insrc, creates a link atdest/filepath pointing to that path:

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

Keyword arguments:

  • dereference_root: false - ifsrc is a symbolic link, does not dereference it.

  • noop: true - does not create links.

  • remove_destination: true - removesdest before creating links.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    cp -lr src0 dest0cp -lr src1 dest1cp -lr src2/sub0 src2/sub1 dest2

Raises an exception ifdest is the path to an existing file or directory and keyword argumentremove_destination: true is not given.

Related:methods for copying.

Source
# File lib/fileutils.rb, line 982defcp_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 ' '}"ifverbosereturnifnoopfu_each_src_dest(src,dest)do|s,d|copy_entrys,d,preserve,dereference_root,remove_destinationendend

Recursively copies files.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

The mode, owner, and group are retained in the copy; to change those, useFileUtils.install instead.

Ifsrc is the path to a file anddest is not the path to a directory, copiessrc todest:

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

Ifsrc is the path to a file anddest is the path to a directory, copiessrc todest/src:

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

Ifsrc is the path to a directory anddest does not exist, recursively copiessrc todest:

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

Ifsrc anddest are paths to directories, recursively copiessrc todest/src:

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

Ifsrc is an array of paths anddest is a directory, recursively copies from each path insrc todest; the paths insrc may point to files and/or directories.

Keyword arguments:

  • dereference_root: false - ifsrc is a symbolic link, does not dereference it.

  • noop: true - does not copy files.

  • preserve: true - preserves file times.

  • remove_destination: true - removesdest before copying files.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    cp -r src0.txt dest0.txtcp -r src1.txt dest1cp -r src2 dest2cp -r src3 dest3

Raises an exception ofsrc is the path to a directory anddest is the path to a file.

Related:methods for copying.

Alias for:pwd
Alias for:compare_file
Source
# File lib/fileutils.rb, line 1607definstall(src,dest,mode:nil,owner:nil,group:nil,preserve:nil,noop:nil,verbose:nil)ifverbosemsg =+"install -c"msg<<' -p'ifpreservemsg<<' -m '<<mode_to_s(mode)ifmodemsg<<" -o #{owner}"ifownermsg<<" -g #{group}"ifgroupmsg<<' '<< [src,dest].flatten.join(' ')fu_output_messagemsgendreturnifnoopuid =fu_get_uid(owner)gid =fu_get_gid(group)fu_each_src_dest(src,dest)do|s,d|st =File.stat(s)unlessFile.exist?(d)andcompare_file(s,d)remove_filed,trueifd.end_with?('/')mkdir_pdcopy_files,d+File.basename(s)elsemkdir_pFile.expand_path('..',d)copy_files,dendFile.utimest.atime,st.mtime,difpreserveFile.chmodfu_mode(mode,st),difmodeFile.chownuid,gid,difuidorgidendendend

Copies a file entry. Seeinstall(1).

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths;

If the entry atdest does not exist, copies fromsrc todest:

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

Ifdest is a file entry, copies fromsrc todest, overwriting:

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

Ifdest is a directory entry, copies fromsrc todest/src, overwriting if necessary:

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"

Ifsrc is an array of paths anddest points to a directory, copies each pathpath insrc todest/path:

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

Keyword arguments:

  • group:group - changes the group if notnil, usingFile.chown.

  • mode:permissions - changes the permissions. usingFile.chmod.

  • noop: true - does not copy entries; returnsnil.

  • owner:owner - changes the owner if notnil, usingFile.chown.

  • preserve: true - preserve timestamps usingFile.utime.

  • verbose: true - prints an equivalent command:

    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)

    Output:

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

Related:methods for copying.

Alias for:ln
Source
# File lib/fileutils.rb, line 809deflink_entry(src,dest,dereference_root =false,remove_destination =false)Entry_.new(src,nil,dereference_root).traversedo|ent|destent =Entry_.new(dest,ent.rel,false)File.unlinkdestent.pathifremove_destination&&File.file?(destent.path)ent.linkdestent.pathendend

Createshard links; returnsnil.

Argumentssrc anddest should beinterpretable as paths.

Ifsrc is the path to a file anddest does not exist, creates a hard link atdest pointing tosrc:

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

Ifsrc is the path to a directory anddest does not exist, recursively creates hard links atdest pointing to paths insrc:

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')# => trueFileUtils.link_entry('src1','dest1')File.file?('dest1/dir0/t0.txt')# => trueFile.file?('dest1/dir0/t1.txt')# => trueFile.file?('dest1/dir1/t2.txt')# => trueFile.file?('dest1/dir1/t3.txt')# => true

Optional arguments:

  • dereference_root - dereferencessrc if it is a symbolic link (false by default).

  • remove_destination - removesdest before creating links (false by default).

Raises an exception ifdest is the path to an existing file or directory and optional argumentremove_destination is not given.

Related:FileUtils.ln (has different options).

Source
# File lib/fileutils.rb, line 517defln(src,dest,force:nil,noop:nil,verbose:nil)fu_output_message"ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}"ifverbosereturnifnoopfu_each_src_dest0(src,dest)do|s,d|remove_filed,trueifforceFile.links,dendend

Createshard links.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Whensrc is the path to an existing file anddest is the path to a non-existent file, creates a hard link atdest pointing tosrc; returns zero:

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

Whensrc is the path to an existing file anddest is the path to an existing directory, creates a hard link atdest/src pointing tosrc; returns zero:

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

Whensrc is an array of paths to existing files anddest is the path to an existing directory, then for each pathtarget insrc, creates a hard link atdest/target pointing totarget; returnssrc:

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"]

Keyword arguments:

  • force: true - overwritesdest if it exists.

  • noop: true - does not create links.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    ln tmp0/t.txt tmp1/t.lnkln tmp2/t.dat tmp3ln tmp0/t.txt tmp2/t.dat tmp4/

Raises an exception ifdest is the path to an existing file and keyword argumentforce is nottrue.

Related:FileUtils.link_entry (has different options).

Also aliased as:link
Source
# File lib/fileutils.rb, line 707defln_s(src,dest,force:nil,relative:false,target_directory:true,noop:nil,verbose:nil)ifrelativereturnln_sr(src,dest,force:force,target_directory:target_directory,noop:noop,verbose:verbose)endfu_output_message"ln -s#{force ? 'f' : ''}#{    target_directory ? '' : 'T'} #{[src,dest].flatten.join ' '}"ifverbosereturnifnoopfu_each_src_dest0(src,dest,target_directory)do|s,d|remove_filed,trueifforceFile.symlinks,dendend

Createssymbolic links.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Ifsrc is the path to an existing file:

  • Whendest is the path to a non-existent file, creates a symbolic link atdest pointing tosrc:

    FileUtils.touch('src0.txt')File.exist?('dest0.txt')# => falseFileUtils.ln_s('src0.txt','dest0.txt')File.symlink?('dest0.txt')# => true
  • Whendest is the path to an existing file, creates a symbolic link atdest pointing tosrc if and only if keyword argumentforce: true is given (raises an exception otherwise):

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

Ifdest is the path to a directory, creates a symbolic link atdest/src pointing tosrc:

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

Ifsrc is an array of paths to existing files anddest is a directory, for each childchild insrc creates a symbolic linkdest/child pointing tochild:

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')# => trueFile.symlink?('destdir3/src1.txt')# => true

Keyword arguments:

  • force: true - overwritesdest if it exists.

  • relative: false - create links relative todest.

  • noop: true - does not create links.

  • verbose: true - prints an equivalent command:

    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)

    Output:

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

Related:FileUtils.ln_sf.

Also aliased as:symlink
Source
# File lib/fileutils.rb, line 726defln_sf(src,dest,noop:nil,verbose:nil)ln_ssrc,dest,force:true,noop:noop,verbose:verboseend

LikeFileUtils.ln_s, but always with keyword argumentforce: true given.

Source
# File lib/fileutils.rb, line 733defln_sr(src,dest,target_directory:true,force:nil,noop:nil,verbose:nil)cmd ="ln -s#{force ? 'f' : ''}#{target_directory ? '' : 'T'}"ifverbosefu_each_src_dest0(src,dest,target_directory)do|s,d|iftarget_directoryparent =File.dirname(d)destdirs =fu_split_path(parent)real_ddirs =fu_split_path(File.realpath(parent))elsedestdirs||=fu_split_path(dest)real_ddirs||=fu_split_path(File.realdirpath(dest))endsrcdirs =fu_split_path(s)i =fu_common_components(srcdirs,destdirs)n =destdirs.size-in-=1unlesstarget_directorylink1 =fu_clean_components(*Array.new([n,0].max,'..'),*srcdirs[i..-1])beginreal_sdirs =fu_split_path(File.realdirpath(s))rescuenilrescueelsei =fu_common_components(real_sdirs,real_ddirs)n =real_ddirs.size-in-=1unlesstarget_directorylink2 =fu_clean_components(*Array.new([n,0].max,'..'),*real_sdirs[i..-1])link1 =link2iflink1.size>link2.sizeends =File.join(link1)fu_output_message [cmd,s,d].flatten.join(' ')ifverbosenextifnoopremove_filed,trueifforceFile.symlinks,dendend

LikeFileUtils.ln_s, but create links relative todest.

Alias for:mkdir_p
Source
# File lib/fileutils.rb, line 317defmkdir(list,mode:nil,noop:nil,verbose:nil)list =fu_list(list)fu_output_message"mkdir #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}"ifverbosereturnifnooplist.eachdo|dir|fu_mkdirdir,modeendend

Creates directories at the paths in the givenlist (a single path or an array of paths); returnslist if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

With no keyword arguments, creates a directory at eachpath inlist by calling:Dir.mkdir(path, mode); seeDir.mkdir:

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

Keyword arguments:

  • mode:mode - also callsFile.chmod(mode, path); seeFile.chmod.

  • noop: true - does not create directories.

  • verbose: true - prints an equivalent command:

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

    Output:

    mkdir tmp0 tmp1mkdir -m 700 tmp2 tmp3

Raises an exception if any path points to an existing file or directory, or if for any reason a directory cannot be created.

Related:FileUtils.mkdir_p.

Source
# File lib/fileutils.rb, line 366defmkdir_p(list,mode:nil,noop:nil,verbose:nil)list =fu_list(list)fu_output_message"mkdir -p #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}"ifverbosereturn*listifnooplist.eachdo|item|path =remove_trailing_slash(item)stack = []untilFile.directory?(path)||File.dirname(path)==pathstack.pushpathpath =File.dirname(path)endstack.reverse_eachdo|dir|beginfu_mkdirdir,moderescueSystemCallErrorraiseunlessFile.directory?(dir)endendendreturn*listend

Creates directories at the paths in the givenlist (a single path or an array of paths), also creating ancestor directories as needed; returnslist if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

With no keyword arguments, creates a directory at eachpath inlist, along with any needed ancestor directories, by calling:Dir.mkdir(path, mode); seeDir.mkdir:

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

Keyword arguments:

  • mode:mode - also callsFile.chmod(mode, path); seeFile.chmod.

  • noop: true - does not create directories.

  • verbose: true - prints an equivalent command:

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

    Output:

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

Raises an exception if for any reason a directory cannot be created.

FileUtils.mkpath andFileUtils.makedirs are aliases forFileUtils.mkdir_p.

Related:FileUtils.mkdir.

Also aliased as:mkpath,makedirs
Alias for:mkdir_p
Alias for:mv
Source
# File lib/fileutils.rb, line 1154defmv(src,dest,force:nil,noop:nil,verbose:nil,secure:nil)fu_output_message"mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}"ifverbosereturnifnoopfu_each_src_dest(src,dest)do|s,d|destent =Entry_.new(d,nil,true)beginifdestent.exist?ifdestent.directory?raiseErrno::EEXIST,dendendbeginFile.renames,drescueErrno::EXDEV,Errno::EPERM# move from unencrypted to encrypted dir (ext4)copy_entrys,d,trueifsecureremove_entry_secures,forceelseremove_entrys,forceendendrescueSystemCallErrorraiseunlessforceendendend

Moves entries.

Argumentssrc (a single path or an array of paths) anddest (a single path) should beinterpretable as paths.

Ifsrc anddest are on different file systems, first copies, then removessrc.

May cause a local vulnerability if not called with keyword argumentsecure: true; seeAvoiding the TOCTTOU Vulnerability.

Ifsrc is the path to a single file or directory anddest does not exist, movessrc todest:

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

Ifsrc is an array of paths to files and directories anddest is the path to a directory, copies from each path in the array todest:

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

Keyword arguments:

  • force: true - if the move includes removingsrc (that is, ifsrc anddest are on different file systems), ignores raised exceptions ofStandardError and its descendants.

  • noop: true - does not move files.

  • secure: true - removessrc securely; see details atFileUtils.remove_entry_secure.

  • verbose: true - prints an equivalent command:

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

    Output:

    mvsrc0dest0mvsrc1.txtsrc1dest1
Also aliased as:move
Source
# File lib/fileutils.rb, line 198defpwdDir.pwdend

Returns a string containing the path to the current directory:

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

Related:FileUtils.cd.

Also aliased as:getwd
Alias for:rm
Source
# File lib/fileutils.rb, line 1489defremove_dir(path,force =false)raiseErrno::ENOTDIR,pathunlessforceorFile.directory?(path)remove_entrypath,forceend

Recursively removes the directory entry given bypath, which should be the entry for a regular file, a symbolic link, or a directory.

Argumentpath should beinterpretable as a path.

Optional argumentforce specifies whether to ignore raised exceptions ofStandardError and its descendants.

Related:methods for deleting.

Source
# File lib/fileutils.rb, line 1446defremove_entry(path,force =false)Entry_.new(path).postorder_traversedo|ent|beginent.removerescueraiseunlessforceendendrescueraiseunlessforceend

Removes the entry given bypath, which should be the entry for a regular file, a symbolic link, or a directory.

Argumentpath should beinterpretable as a path.

Optional argumentforce specifies whether to ignore raised exceptions ofStandardError and its descendants.

Related:FileUtils.remove_entry_secure.

Source
# File lib/fileutils.rb, line 1348defremove_entry_secure(path,force =false)unlessfu_have_symlink?remove_entrypath,forcereturnendfullpath =File.expand_path(path)st =File.lstat(fullpath)unlessst.directory?File.unlinkfullpathreturnend# is a directory.parent_st =File.stat(File.dirname(fullpath))unlessparent_st.world_writable?remove_entrypath,forcereturnendunlessparent_st.sticky?raiseArgumentError,"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 rooteuid =Process.euiddot_file =fullpath+"/."beginFile.open(dot_file) {|f|unlessfu_stat_identical_entry?(st,f.stat)# symlink (TOC-to-TOU attack?)File.unlinkfullpathreturnendf.chowneuid,-1f.chmod0700    }rescueErrno::EISDIR# JRuby in non-native mode can't open files as dirsFile.lstat(dot_file).tap {|fstat|unlessfu_stat_identical_entry?(st,fstat)# symlink (TOC-to-TOU attack?)File.unlinkfullpathreturnendFile.chowneuid,-1,dot_fileFile.chmod0700,dot_file    }endunlessfu_stat_identical_entry?(st,File.lstat(fullpath))# TOC-to-TOU attack?File.unlinkfullpathreturnend# ---- tree root is frozen ----root =Entry_.new(path)root.preorder_traversedo|ent|ifent.directory?ent.chowneuid,-1ent.chmod0700endendroot.postorder_traversedo|ent|beginent.removerescueraiseunlessforceendendrescueraiseunlessforceend

Securely removes the entry given bypath, which should be the entry for a regular file, a symbolic link, or a directory.

Argumentpath should beinterpretable as a path.

Avoids a local vulnerability that can exist in certain circumstances; seeAvoiding the TOCTTOU Vulnerability.

Optional argumentforce specifies whether to ignore raised exceptions ofStandardError and its descendants.

Related:methods for deleting.

Source
# File lib/fileutils.rb, line 1470defremove_file(path,force =false)Entry_.new(path).remove_filerescueraiseunlessforceend

Removes the file entry given bypath, which should be the entry for a regular file or a symbolic link.

Argumentpath should beinterpretable as a path.

Optional argumentforce specifies whether to ignore raised exceptions ofStandardError and its descendants.

Related:methods for deleting.

Source
# File lib/fileutils.rb, line 1213defrm(list,force:nil,noop:nil,verbose:nil)list =fu_list(list)fu_output_message"rm#{force ? ' -f' : ''} #{list.join ' '}"ifverbosereturnifnooplist.eachdo|path|remove_filepath,forceendend

Removes entries at the paths in the givenlist (a single path or an array of paths) returnslist, if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

With no keyword arguments, removes files at the paths given inlist:

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

Keyword arguments:

  • force: true - ignores raised exceptions ofStandardError and its descendants.

  • noop: true - does not remove files; returnsnil.

  • verbose: true - prints an equivalent command:

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

    Output:

    rmsrc0.datsrc0.txt

Related:methods for deleting.

Also aliased as:remove
Source
# File lib/fileutils.rb, line 1238defrm_f(list,noop:nil,verbose:nil)rmlist,force:true,noop:noop,verbose:verboseend

Equivalent to:

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

Argumentlist (a single path or an array of paths) should beinterpretable as paths.

SeeFileUtils.rm for keyword arguments.

Related:methods for deleting.

Also aliased as:safe_unlink
Source
# File lib/fileutils.rb, line 1296defrm_r(list,force:nil,noop:nil,verbose:nil,secure:nil)list =fu_list(list)fu_output_message"rm -r#{force ? 'f' : ''} #{list.join ' '}"ifverbosereturnifnooplist.eachdo|path|ifsecureremove_entry_securepath,forceelseremove_entrypath,forceendendend

Removes entries at the paths in the givenlist (a single path or an array of paths); returnslist, if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

May cause a local vulnerability if not called with keyword argumentsecure: true; seeAvoiding the TOCTTOU Vulnerability.

For each file path, removes the file at that path:

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

For each directory path, recursively removes files and directories:

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

Keyword arguments:

  • force: true - ignores raised exceptions ofStandardError and its descendants.

  • noop: true - does not remove entries; returnsnil.

  • secure: true - removessrc securely; see details atFileUtils.remove_entry_secure.

  • verbose: true - prints an equivalent command:

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

    Output:

    rm -r src0.dat src0.txtrm -r src1

Related:methods for deleting.

Source
# File lib/fileutils.rb, line 1325defrm_rf(list,noop:nil,verbose:nil,secure:nil)rm_rlist,force:true,noop:noop,verbose:verbose,secure:secureend

Equivalent to:

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

Argumentlist or its elements should beinterpretable as paths.

May cause a local vulnerability if not called with keyword argumentsecure: true; seeAvoiding the TOCTTOU Vulnerability.

SeeFileUtils.rm_r for keyword arguments.

Related:methods for deleting.

Also aliased as:rmtree
Source
# File lib/fileutils.rb, line 443defrmdir(list,parents:nil,noop:nil,verbose:nil)list =fu_list(list)fu_output_message"rmdir #{parents ? '-p ' : ''}#{list.join ' '}"ifverbosereturnifnooplist.eachdo|dir|Dir.rmdir(dir =remove_trailing_slash(dir))ifparentsbeginuntil (parent =File.dirname(dir))=='.'orparent==dirdir =parentDir.rmdir(dir)endrescueErrno::ENOTEMPTY,Errno::EEXIST,Errno::ENOENTendendendend

Removes directories at the paths in the givenlist (a single path or an array of paths); returnslist, if it is an array,[list] otherwise.

Argumentlist or its elements should beinterpretable as paths.

With no keyword arguments, removes the directory at eachpath inlist, by calling:Dir.rmdir(path); seeDir.rmdir:

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

Keyword arguments:

  • parents: true - removes successive ancestor directories if empty.

  • noop: true - does not remove directories.

  • verbose: true - prints an equivalent command:

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

    Output:

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

Raises an exception if a directory does not exist or if for any reason a directory cannot be removed.

Related:methods for deleting.

Alias for:rm_rf
Alias for:rm_f
Alias for:ln_s
Source
# File lib/fileutils.rb, line 2004deftouch(list,noop:nil,verbose:nil,mtime:nil,nocreate:nil)list =fu_list(list)t =mtimeifverbosefu_output_message"touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}"endreturnifnooplist.eachdo|path|created =nocreatebeginFile.utime(t,t,path)rescueErrno::ENOENTraiseifcreatedFile.open(path,'a') {        ;      }created =trueretryiftendendend

Updates modification times (mtime) and access times (atime) of the entries given by the paths inlist (a single path or an array of paths); returnslist if it is an array,[list] otherwise.

By default, creates an empty file for any path to a non-existent entry; use keyword argumentnocreate to raise an exception instead.

Argumentlist or its elements should beinterpretable as paths.

Examples:

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

Keyword arguments:

  • mtime:time - sets the entry’s mtime to the given time, instead of the current time.

  • nocreate: true - raises an exception if the entry does not exist.

  • noop: true - does not touch entries; returnsnil.

  • verbose: true - prints an equivalent command:

    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)

    Output:

    touchsrc0.txttouchsrc0.txtsrc0.dattouchsrc0.txt

Related:FileUtils.uptodate?.

Source
# File lib/fileutils.rb, line 265defuptodate?(new,old_list)returnfalseunlessFile.exist?(new)new_time =File.mtime(new)old_list.eachdo|old|ifFile.exist?(old)returnfalseunlessnew_time>File.mtime(old)endendtrueend

Returnstrue if the file at pathnew is newer than all the files at paths in arrayold_list;false otherwise.

Argumentnew and the elements ofold_list should beinterpretable as paths:

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

A non-existent file is considered to be infinitely old.

Related:FileUtils.touch.