module Benry::UnixCommand
Constants
- BENRY_ECHOBACK
- CHMOD_MODES
Public Instance Methods
__echo(cmd, args)
click to toggle source
# File lib/benry/unixcmd.rb, line 57 def __echo(cmd, args) #; [!mzbdj] echoback command arguments. optchars = __prepare(cmd, args, "n", nil) not_nl = optchars.include?('n') #; [!cjggd] prints arguments. #; [!vhpw3] not print newline at end if '-n' option specified. print args.join(" ") puts "" unless not_nl end
__echoback?()
click to toggle source
alias fu_output_message echoback private :fu_output_message
# File lib/benry/unixcmd.rb, line 46 def __echoback?() return self.class.const_get(:BENRY_ECHOBACK) end
__err(msg)
click to toggle source
# File lib/benry/unixcmd.rb, line 24 def __err(msg) raise ArgumentError.new(msg) end
__mkpath(dirpath, pathcache={})
click to toggle source
# File lib/benry/unixcmd.rb, line 1032 def __mkpath(dirpath, pathcache={}) if ! pathcache.include?(dirpath) parent = File.dirname(dirpath) __mkpath(parent, pathcache) unless parent == dirpath Dir.mkdir(dirpath) unless File.exist?(dirpath) pathcache[dirpath] = true end end
__ruby(cmd, args, ignore_error, &b)
click to toggle source
# File lib/benry/unixcmd.rb, line 106 def __ruby(cmd, args, ignore_error, &b) #; [!98qro] echoback command and args. #; [!u5f5l] run ruby command. #; [!2jano] returns process status object if ruby command succeeded. #; [!69clt] (ruby) error when ruby command failed. #; [!z1f03] (ruby!) ignores error even when ruby command failed. ruby = RbConfig.ruby if args.length == 1 __sys(cmd, ["#{ruby} #{args[0]}"], ignore_error, &b) else __sys(cmd, [ruby]+args, ignore_error, &b) end end
__store(cmd, args, overwrite, to:)
click to toggle source
# File lib/benry/unixcmd.rb, line 990 def __store(cmd, args, overwrite, to:) #; [!9wr1o] error when `to:` keyword argument not specified. ! to.nil? or __err "#{cmd}: 'to:' keyword argument required." #; [!n43u2] echoback command and arguments. optchars = __prepare(cmd, args, "pfl", to) preserve = optchars.include?("p") ignore = optchars.include?("f") hardlink = optchars.include?("l") #; [!588e5] error when destination directory not exist. #; [!lm43y] error when destination pattern matched to multiple filenames. #; [!u5zoy] error when destination is not a directory. dir = __glob_onedir(cmd, to) #; [!g1duw] error when absolute path specified. args.each do |arg| #! File.absolute_path?(arg) or # Ruby >= 2.7 File.absolute_path(arg) != arg or __err "#{cmd}: #{arg}: absolute path not expected (only relative path expected)." end #; [!je1i2] error when file not exist but '-f' option not specified. filenames = __glob_filenames(cmd, args, ignore) #; [!5619q] (store) error when target file or directory already exists. #; [!cw08t] (store!) overwrites existing files. if ! overwrite filenames.each do |fpath| newpath = File.join(dir, fpath) ! File.exist?(newpath) or __err "#{cmd}: #{newpath}: destination file or directory already exists." end end #; [!4y4zy] copy files with keeping filepath. #; [!f0n0y] copy timestamps if '-p' option specified. #; [!w8oq6] creates hard links if '-l' option specified. #; [!7n869] error when copying supecial files such as character device. pathcache = {} filenames.each do |fpath| newpath = File.join(dir, fpath) __mkpath(File.dirname(newpath), pathcache) __cp_file(cmd, fpath, newpath, preserve, hardlink, bufsize=4096) end end
__sys(cmd, args, ignore_error) { |stat| ... }
click to toggle source
# File lib/benry/unixcmd.rb, line 76 def __sys(cmd, args, ignore_error, &b) #; [!rqe7a] echoback command and arguments. echoback(args.join(" ")) if __echoback?() result = system(*args) #; [!agntr] returns process status if command succeeded. #; [!clfig] yields block if command failed. #; [!deu3e] not yield block if command succeeded. #; [!chko8] block argument is process status. #; [!0yy6r] (sys) not raise error if block result is truthy #; [!xsspi] (sys) raises error if command failed. #; [!tbfii] (sys!) returns process status if command failed. stat = $? return stat if result if block_given?() result = yield stat return stat if result end return stat if ignore_error raise "Command failed with status (#{$?.exitstatus}): #{args.join(' ')}" end
__unzip(cmd, args, overwrite)
click to toggle source
# File lib/benry/unixcmd.rb, line 1131 def __unzip(cmd, args, overwrite) #; [!eqx48] requires 'zip' gem automatically. require 'zip' unless defined?(::Zip) #; [!ednxk] echoback command and arguments. optchars = __prepare(cmd, args, "d", nil) outdir = optchars.include?('d') ? args.shift() : nil #; [!1lul7] error if zip file not specified. zip_filename = args.shift() or __err "#{cmd}: zip filename required." #; [!0yyg8] target directory should not exist, or be empty. if outdir if ! File.exist?(outdir) # pass elsif File.directory?(outdir) #; [!1ls2h] error if target directory not empty. found = Dir.open(outdir) {|dir| dir.find {|x| x != '.' && x != '..' } } ! found or __err "#{cmd}: #{outdir}: directory not empty." else #; [!lb6r5] error if target directory is not a directory. __err "#{cmd}: #{outdir}: not a directory." end end #; [!o1ot5] expands glob pattern. #; [!92bh4] error if glob pattern matched to multiple filenames. #; [!esnke] error if zip file not found. arr = Dir.glob(zip_filename); n = arr.length if n < 1 ; __err "#{cmd}: #{zip_filename}: zip file not found." elsif n > 1 ; __err "#{cmd}: #{zip_filename}: matched to multiple filenames (#{arr.sort.join(' ')})." else ; zip_filename = arr[0] end # filenames = args filenames = nil if filenames.empty? #; [!dzk7c] creates target directory if not exists. __mkpath(outdir, {}) if outdir && ! File.exist?(outdir) # orig = ::Zip.on_exists_proc begin #; [!06nyv] (unzip!) overwrites existing files. ::Zip.on_exists_proc = overwrite extglob = File::FNM_EXTGLOB #; [!ekllx] (unzip) error when file already exists. ::Zip::File.open(zip_filename) do |zf| zf.each do |x| next if filenames && ! filenames.find {|pat| File.fnmatch?(pat, x.name, extglob) } #; [!zg60i] error if file has absolute path. outdir || File.absolute_path(x.name) != x.name or __err "#{cmd}: #{x.name}: cannot extract absolute path." # next if x.directory? fpath = outdir ? File.join(outdir, x.name) : x.name overwrite || ! File.exist?(fpath) or __err "#{cmd}: #{fpath}: file already exists (to overwrite it, call `#{cmd}!` command instead of `#{cmd}` command)." end end #; [!0tedi] extract zip file. ::Zip::File.open(zip_filename) do |zf| zf.each do |x| #; [!ikq5w] if filenames are specified, extracts files matched to them. next if filenames && ! filenames.find {|pat| File.fnmatch?(pat, x.name, extglob) } #; [!dy4r4] if '-d' option specified, extracts files under target directory. if outdir x.extract(File.join(outdir, x.name)) #; [!5u645] if '-d' option not specified, extracts files under current directory. else x.extract() end end end ensure #; [!sjf80] (unzip!) `Zip.on_exists_proc` should be recovered. ::Zip.on_exists_proc = orig end end
__zip(cmd, args, overwrite)
click to toggle source
# File lib/benry/unixcmd.rb, line 1050 def __zip(cmd, args, overwrite) #; [!zzvuk] requires 'zip' gem automatically. require 'zip' unless defined?(::Zip) #; [!zk1qt] echoback command and arguments. optchars = __prepare(cmd, args, "r0123456789", nil) recursive = optchars.include?('r') complevel = (optchars =~ /(\d)/ ? $1.to_i : nil) #; [!lrnj7] zip filename required. zip_filename = args.shift() or __err "#{cmd}: zip filename required." #; [!khbiq] zip filename can be glob pattern. #; [!umbal] error when zip file glob pattern matched to mutilple filenames. arr = Dir.glob(zip_filename); n = arr.length if n < 1 ; nil elsif n > 1 ; __err "#{cmd}: #{zip_filename}: matched to multiple filenames (#{arr.sort.join(', ')})." else ; zip_filename = arr[0] end #; [!oqzna] (zip) raises error if zip file already exists. ! File.exist?(zip_filename) || overwrite or __err "#{cmd}: #{zip_filename}: already exists (to overwrite it, call `#{cmd}!` command instead of `#{cmd}` command)." #; [!uu8uz] expands glob pattern. #; [!nahxa] error if file not exist. filenames = __glob_filenames(cmd, args, false) do |arg, _| __err "#{cmd}: #{arg}: file or directory not found." end #; [!qsp7c] cannot specify absolute path. filenames.each do |fname| if File.absolute_path(fname) == fname # Ruby >= 2.7: File.absolute_path?() __err "#{cmd}: #{fname}: not support absolute path." end end #; [!e995z] (zip!) removes zip file if exists. File.unlink(zip_filename) if File.exist?(zip_filename) #; [!3sxmg] supports complession level (0~9). orig = Zip.default_compression Zip.default_compression = complevel if complevel #; [!p8alf] creates zip file. begin zipf = ::Zip::File.open(zip_filename, create: true) do |zf| # `compression_level: n` doesn't work. why? filenames.each do |fname| __zip_add(cmd, zf, fname, recursive) end zf end ensure #; [!h7yxl] restores value of `Zip.default_compression`. Zip.default_compression = orig if complevel end #; [!fvvn8] returns zip file object. return zipf end
__zip_add(cmd, zf, fpath, recursive)
click to toggle source
# File lib/benry/unixcmd.rb, line 1102 def __zip_add(cmd, zf, fpath, recursive) ftype = File.ftype(fpath) case ftype when 'link'; zf.add(fpath, fpath) when 'file'; zf.add(fpath, fpath) when 'directory' zf.add(fpath, fpath) #; [!bgdg7] adds files recursively into zip file if '-r' option specified. Dir.open(fpath) do |dir| dir.each do |x| next if x == '.' || x == '..' __zip_add(cmd, zf, File.join(fpath, x), recursive) end end if recursive else #; [!jgt96] error when special file specified. __err "#{cmd}: #{fpath}: #{ftype} file not supported." end end
atomic_symlink!(src, dst)
click to toggle source
# File lib/benry/unixcmd.rb, line 739 def atomic_symlink!(src, dst) cmd = 'atomic_symlink!' #; [!gzp4a] creates temporal symlink and rename it when symlink already exists. #; [!lhomw] creates temporal symlink and rename it when symlink not exist. if File.symlink?(dst) || ! File.exist?(dst) tmp = "#{dst}.#{rand().to_s[2..5]}" echoback("ln -s #{src} #{tmp} && mv -Tf #{tmp} #{dst}") if __echoback?() File.symlink(src, tmp) File.rename(tmp, dst) #; [!h75kp] error when destination is normal file or directory. else __err "#{cmd}: #{dst}: not a symbolic link." end end
capture2( *args, **kws)
click to toggle source
# File lib/benry/unixcmd.rb, line 134 def capture2( *args, **kws); __capture(:capture2 , args, kws, false); end
capture2!( *args, **kws)
click to toggle source
# File lib/benry/unixcmd.rb, line 137 def capture2!( *args, **kws); __capture(:capture2 , args, kws, true ); end
capture2e( *args, **kws)
click to toggle source
# File lib/benry/unixcmd.rb, line 135 def capture2e( *args, **kws); __capture(:capture2e, args, kws, false); end
capture2e!(*args, **kws)
click to toggle source
# File lib/benry/unixcmd.rb, line 138 def capture2e!(*args, **kws); __capture(:capture2e, args, kws, true ); end
capture3( *args, **kws)
click to toggle source
# File lib/benry/unixcmd.rb, line 136 def capture3( *args, **kws); __capture(:capture3 , args, kws, false); end
capture3!( *args, **kws)
click to toggle source
# File lib/benry/unixcmd.rb, line 139 def capture3!( *args, **kws); __capture(:capture3 , args, kws, true ); end
cd(arg) { || ... }
click to toggle source
# File lib/benry/unixcmd.rb, line 162 def cd(arg, &b) cmd = 'cd' #; [!gnmdg] expands file pattern. #; [!v7bn7] error when pattern not matched to any file. #; [!08wuv] error when pattern matched to multiple files. #; [!hs7u8] error when argument is not a directory name. dir = __glob_onedir(cmd, arg) #; [!cg5ns] changes current directory. here = Dir.pwd echoback("cd #{dir}") if __echoback?() Dir.chdir(dir) #; [!uit6q] if block given, then back to current dir. if block_given?() @__depth ||= 0 @__depth += 1 begin yield ensure @__depth -= 1 echoback("cd -") if __echoback?() Dir.chdir(here) end end #; [!cg298] returns path before changing directory. return here end
Also aliased as: chdir
chmod(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 822 def chmod(*args) __chmod("chmod", args) end
chown(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 909 def chown(*args) __chown("chown", args) end
cp(*args, to: nil)
click to toggle source
# File lib/benry/unixcmd.rb, line 306 def cp(*args, to: nil) __cp('cp', args, to: to, overwrite: false) end
cp!(*args, to: nil)
click to toggle source
# File lib/benry/unixcmd.rb, line 310 def cp!(*args, to: nil) __cp('cp!', args, to: to, overwrite: true) end
echo(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 53 def echo(*args) __echo('echo', args) end
echoback(cmd)
click to toggle source
# File lib/benry/unixcmd.rb, line 39 def echoback(cmd) #; [!x7atu] prints argument string into $stdout with prompt. puts "#{prompt!(@__depth ||= 0)}#{cmd}" end
ln(*args, to: nil)
click to toggle source
# File lib/benry/unixcmd.rb, line 634 def ln(*args, to: nil) __ln('ln', args, to: to, overwrite: false) end
ln!(*args, to: nil)
click to toggle source
# File lib/benry/unixcmd.rb, line 638 def ln!(*args, to: nil) __ln('ln!', args, to: to, overwrite: true) end
mkdir(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 529 def mkdir(*args) __mkdir('mkdir', args) end
mv(*args, to: nil)
click to toggle source
# File lib/benry/unixcmd.rb, line 432 def mv(*args, to: nil) __mv('mv', args, to: to, overwrite: false) end
mv!(*args, to: nil)
click to toggle source
# File lib/benry/unixcmd.rb, line 436 def mv!(*args, to: nil) __mv('mv!', args, to: to, overwrite: true) end
prompt()
click to toggle source
# File lib/benry/unixcmd.rb, line 29 def prompt() #; [!uilyk] returns prompt string. return "$" end
prompt!(depth)
click to toggle source
# File lib/benry/unixcmd.rb, line 34 def prompt!(depth) #; [!q992e] adds indentation after prompt. return prompt() + ' ' * (depth+1) end
pushd(arg) { || ... }
click to toggle source
# File lib/benry/unixcmd.rb, line 190 def pushd(arg, &b) cmd = 'pushd' #; [!xl6lg] raises error when block not given. block_given?() or raise ArgumentError, "pushd: requires block argument." #; [!nvkha] expands file pattern. #; [!q3itn] error when pattern not matched to any file. #; [!hveaj] error when pattern matched to multiple files. #; [!y6cq9] error when argument is not a directory name. dir = __glob_onedir(cmd, arg) #; [!7ksfd] replaces home path with '~'. here = Dir.pwd home = File.expand_path("~") here2 = here.start_with?(home) ? here.sub(home, "~") : here #; [!rxtd0] changes directory and yields block. echoback("pushd #{dir}") if __echoback?() @__depth ||= 0 @__depth += 1 Dir.chdir(dir) yield @__depth -= 1 #; [!9jszw] back to origin directory after yielding block. echoback("popd # back to #{here2}") if __echoback?() Dir.chdir(here) here end
pwd()
click to toggle source
# File lib/benry/unixcmd.rb, line 755 def pwd() #; [!aelx6] echoback command and arguments. echoback("pwd") if __echoback?() #; [!kh3l2] prints current directory path. puts Dir.pwd end
rm(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 496 def rm(*args) __rm('rm', args) end
rmdir(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 593 def rmdir(*args) __rmdir('rmdir', args) end
ruby(*args, &b)
click to toggle source
# File lib/benry/unixcmd.rb, line 98 def ruby(*args, &b) __ruby('ruby', args, false, &b) end
ruby!(*args, &b)
click to toggle source
# File lib/benry/unixcmd.rb, line 102 def ruby!(*args, &b) __ruby('ruby!', args, true, &b) end
store(*args, to:)
click to toggle source
# File lib/benry/unixcmd.rb, line 982 def store(*args, to:) __store('store', args, false, to: to) end
store!(*args, to:)
click to toggle source
# File lib/benry/unixcmd.rb, line 986 def store!(*args, to:) __store('store!', args, true, to: to) end
sys(*args, &b)
click to toggle source
# File lib/benry/unixcmd.rb, line 68 def sys(*args, &b) __sys('sh', args, false, &b) end
sys!(*args, &b)
click to toggle source
# File lib/benry/unixcmd.rb, line 72 def sys!(*args, &b) __sys('sh!', args, true, &b) end
time(format=nil) { || ... }
click to toggle source
# File lib/benry/unixcmd.rb, line 1210 def time(format=nil, &b) #; [!ddl3a] measures elapsed time of block and reports into stderr. pt1 = Process.times() t1 = Time.new yield t2 = Time.new pt2 = Process.times() user = pt2.cutime - pt1.cutime sys = pt2.cstime - pt1.cstime real = t2 - t1 format ||= " %.3fs real %.3fs user %.3fs sys" $stderr.puts "" $stderr.puts format % [real, user, sys] end
touch(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 763 def touch(*args) __touch('touch', *args) end
unzip(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 1123 def unzip(*args) __unzip('unzip', args, false) end
unzip!(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 1127 def unzip!(*args) __unzip('unzip!', args, true) end
zip(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 1042 def zip(*args) __zip('zip', args, false) end
zip!(*args)
click to toggle source
# File lib/benry/unixcmd.rb, line 1046 def zip!(*args) __zip('zip', args, true) end