Module: ShellHelpers::SysUtils
Constant Summary collapse
- SysError =
Class.new(StandardError)
Instance Method Summary collapse
-
#blkid(*args, sudo: false) ⇒ Object
output should be the result of
blkid -o export ...
return a list of things like :label=>"swap", :uuid=>"82af0d2f-5ef6-418a-8656-bdfe843f19e1", :type=>"swap", :partlabel=>"swap", :partuuid=>"f4eef373-0803-4701-bd47-b968c44065a6" SH.blkid => {:devname=>"/dev/sda1", :sec_type=>"msdos", :label_fatboot=>"boot", :label=>"boot", :uuid=>"D906-BEB0", :partlabel=>"boot", :partuuid=>"...",:fstype=>"vfat", ...}. -
#find_device(props) ⇒ Object
like find_devices but warn out if the result is of length > 1.
-
#find_devices(props, method: :all) ⇒ Object
find devices matching props SH.find_devices("boot") => [:label=>"boot", :uuid=>"D906-BEB0", :partlabel=>"boot", :partuuid=>"...", :parttype=>"c12a7328-f81f-11d2-ba4b-00a0c93ec93b", :devtype=>"part", :fstype=>"vfat"].
-
#findmnt(sudo: false) ⇒ Object
use findmnt to get infos about mount points SH.findmnt => {:mountpoint=>"/", :devname=>"/dev/bcache0[/slash]", :fstype=>"btrfs", :mountoptions=> ["rw", "noatime", "compress=lzo", "ssd", "space_cache", "autodefrag", "subvolid=257", "subvol=/slash"], :label=>"rootleaf", :uuid=>"1db5b600-df3e-4d1e-9eef-6a0a7fda491d", :partlabel=>"", :partuuid=>"", :fsroot=>"/slash", ...}.
-
#fs_infos(mode: :devices) ⇒ Object
we default to lsblk findmnt adds the subvolumes, the fsroot and the mountoptions.
-
#losetup(img) ⇒ Object
runs losetup, and returns the created disk, and a lambda to close.
-
#lsblk(sudo: false) ⇒ Object
use lsblk to get infos about devices SH.lsblk => :devtype=>"disk", "/dev/sda1"=> :label=>"boot", :uuid=>"D906-BEB0", :partlabel=>"boot", :partuuid=>"00000000-0000-0000-0000-000000000000", :parttype=>"c12a7328-f81f-11d2-ba4b-00a0c93ec93b", :devtype=>"part", :fstype=>"vfat",...}.
-
#make_btrfs_subvolume(dir, check: true) ⇒ Object
makes a btrfs subvolume.
-
#make_dir_or_subvolume(dir) ⇒ Object
try to make a subvolume, else fallsback to a dir.
-
#make_fs(fs, check: true) ⇒ Object
make filesystems takes a list of fs infos (where the device is specified like before, via devname, label, ...).
-
#make_partitions(partitions, check: true, partprobe: true) ⇒ Object
@options: - check => check that no partitions exist first - partprobe: run partprobe if we made partitions SH.make_partitions( {:parttype=>:boot, :partlength=>"+100M", :fstype=>"vfat", :rel_mountpoint=>"boot", :mountoptions=>["fmask=133"], :slash=> :fstype=>"ext4", :rel_mountpoint=>".", ...}).
-
#make_raw_image(name, size = "1G") ⇒ Object
use fallocate to make a raw image.
-
#mount(paths, mkpath: true, abort_on_error: true, sort: true) ⇒ Object
Mount devices on paths - paths: Array (or Hash) of path => path: "/mnt", mountoptions: [], fstype: "ext4", subvol: ..., device_info where device_info is used to find the device via find_device so can be set via :devname, or uuid label partuuid partlabel parttype - sort: sort the mountpoints - abort_on_error: fail if a mount failt - mkpath: mkpath the mountpoints the paths and a lambda to unmount.
- #parse_blkid(output) ⇒ Object
-
#partition_infos(device, sudo: false) ⇒ Object
SH.partition_infos("/dev/sda", sudo: true) => [:partattributes=>"0000000000000004", :partuuid=>"00000000-0000-0000-0000-000000000000", :parttype=>"c12a7328-f81f-11d2-ba4b-00a0c93ec93b", :partattributes=>"0000000000000000", :partuuid=>"f4eef373-0803-4701-bd47-b968c44065a6", :parttype=>"0fc63daf-8483-4772-8e79-3d69d8477de4", :partattributes=>"0000000000000000", :partuuid=>"31b4cd66-39ab-4c5b-a229-d5d2010d53dd", :parttype=>"0fc63daf-8483-4772-8e79-3d69d8477de4"].
-
#partition_type(type, mode: :guid) ⇒ Object
by default give symbol => guid can also give symbol => hexa (mode: :hexa) or hexa/guid => symbol (mode: :symbol).
- #refresh_blkid_cache ⇒ Object
-
#stat_file(file) ⇒ Object
wrap 'stat' SH.stat_file("mine") => :blocknumber=>0,....
-
#stat_filesystem(file, up: true) ⇒ Object
wrap stat --file-system SH.stat_filesystem("mine") => fstype=>"btrfs".
- #umount(paths, sort: true) ⇒ Object
- #wipefs(disk) ⇒ Object
- #zap_partitions(disk) ⇒ Object
Instance Method Details
#blkid(*args, sudo: false) ⇒ Object
output should be the result of blkid -o export ...
return a list of things like
:label=>"swap",
:uuid=>"82af0d2f-5ef6-418a-8656-bdfe843f19e1",
:type=>"swap",
:partlabel=>"swap",
:partuuid=>"f4eef373-0803-4701-bd47-b968c44065a6"
SH.blkid => {:devname=>"/dev/sda1", :sec_type=>"msdos", :label_fatboot=>"boot", :label=>"boot", :uuid=>"D906-BEB0", :partlabel=>"boot", :partuuid=>"...",:fstype=>"vfat", ...}
105 106 107 108 109 |
# File 'lib/shell_helpers/sysutils.rb', line 105 def blkid(*args, sudo: false) # get devname, (part)label/uuid, fstype =Run.run_simple("blkid -o export #{args.shelljoin}", fail_mode: :empty, chomp: true, sudo: sudo) parse_blkid() end |
#find_device(props) ⇒ Object
like find_devices but warn out if the result is of length > 1
226 227 228 229 230 231 232 233 |
# File 'lib/shell_helpers/sysutils.rb', line 226 def find_device(props) devs=find_devices(props) devs=yield(devs) if block_given? devs=[devs].flatten warn "Device #{props} not found" if devs.empty? warn "Several devices for #{props} found: #{devs.map {|d| d&.fetch(:devname)}}" if devs.length >1 return devs.first&.fetch(:devname) end |
#find_devices(props, method: :all) ⇒ Object
find devices matching props SH.find_devices("boot") => [:label=>"boot", :uuid=>"D906-BEB0", :partlabel=>"boot", :partuuid=>"...", :parttype=>"c12a7328-f81f-11d2-ba4b-00a0c93ec93b", :devtype=>"part", :fstype=>"vfat"]
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/shell_helpers/sysutils.rb', line 172 def find_devices(props, method: :all) props=props.clone return [{devname: props[:devname]}] unless props[:devname].nil? # name is both for label and partlabel if props.key?(:name) props[:label] = props[:name] unless props.key?(:label) props[:partlabel] = props[:name] unless props.key?(:partlabel) end if method==:blkid # try with UUID, then LABEL, then PARTUUID # as soon as we have a non empty label, we return the result of # blkid on it. # # Warning, since 'blkid' can only test one label, we cannot check # that all parameters are valid # search from most discriminant to less discriminant %i(uuid label partuuid partlabel).each do |key| if (label=props[key]) return parse_blkid(%x/blkid -o export -t #{key.to_s.upcase}=#{label.shellescape}/).values end end # unfortunately `blkid PARTTYPE=...` does not work, so we need to parse # ourselves if props[:parttype] find_devices(props, method: :all) end else #method=:all fs=fs_infos # here we check all parameters (ie all defined labels are correct) # however, if none are defined, this return true, so we check that at least one is defined return [] unless %i(uuid label partuuid partlabel parttype).any? {|k| props[k]} return fs.keys.select do |k| fsprops=fs[k] next false if (disk=props[:disk]) && !fsprops[:devname].start_with?(disk.to_s) # all defined labels should match next false unless %i(uuid label partuuid partlabel parttype).all? do |key| ptype=props[key] ptype=partition_type(ptype) if key==:parttype and ptype.is_a?(Symbol) !ptype or !fsprops[key] or ptype==fsprops[key] end # their should at least be one matching label next false unless %i(uuid label partuuid partlabel parttype).select do |key| ptype=props[key] ptype=partition_type(ptype) if key==:parttype and ptype.is_a?(Symbol) ptype and fsprops[key] and ptype==fsprops[key] end.length > 0 true end.map {|k| fs[k]} end return [] end |
#findmnt(sudo: false) ⇒ Object
use findmnt to get infos about mount points SH.findmnt => {:mountpoint=>"/", :devname=>"/dev/bcache0[/slash]", :fstype=>"btrfs", :mountoptions=> ["rw", "noatime", "compress=lzo", "ssd", "space_cache", "autodefrag", "subvolid=257", "subvol=/slash"], :label=>"rootleaf", :uuid=>"1db5b600-df3e-4d1e-9eef-6a0a7fda491d", :partlabel=>"", :partuuid=>"", :fsroot=>"/slash", ...}
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/shell_helpers/sysutils.rb', line 139 def findmnt(sudo: false) # get devname, mountpoint, mountoptions, (part)label/uuid, fsroot # only looks at mounted devices (but in comparison to lsblk also show # virtual mounts and bind mounts) =SH::Run.run_simple("findmnt --raw -o SOURCE,TARGET,FSTYPE,OPTIONS,LABEL,UUID,PARTLABEL,PARTUUID,FSROOT", fail_mode: :empty, chomp: true, sudo: sudo) fs={} .each_line.to_a[1..-1]&.each do |l| #two ' ' means a missing option, so we want to split on / /, not on ' ' source,target,fstype,,label,uuid,partlabel,partuuid,fsroot=l.chomp.split(/ /) next unless source=~%r(^/dev/) #skip non dev mountpoints =.split(',') fs[source]={mountpoint: target, devname: source, fstype: fstype, mountoptions: , label: label, uuid: uuid, partlabel: partlabel, partuuid: partuuid, fsroot: fsroot} end fs end |
#fs_infos(mode: :devices) ⇒ Object
we default to lsblk findmnt adds the subvolumes, the fsroot and the mountoptions
157 158 159 160 161 162 |
# File 'lib/shell_helpers/sysutils.rb', line 157 def fs_infos(mode: :devices) return findmnt if mode == :mount return lsblk.merge(findmnt) if mode == :all # :devname, :devtype, :mountpoint, [:mountoptions], :label, :uuid, :partlabel, :partuuid, :parttype, :fstype, [:fsroot] lsblk end |
#losetup(img) ⇒ Object
runs losetup, and returns the created disk, and a lambda to close
475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/shell_helpers/sysutils.rb', line 475 def losetup(img) disk = Run.run_simple("losetup -f --show #{img.shellescape}", sudo: true, chomp: true, error_mode: :nil) close=lambda do SH.sh("losetup -d #{disk.shellescape}", sudo: true) if disk end if block_given? begin yield disk ensure close.call end end return disk, close end |
#lsblk(sudo: false) ⇒ Object
use lsblk to get infos about devices SH.lsblk => :devtype=>"disk", "/dev/sda1"=> :label=>"boot", :uuid=>"D906-BEB0", :partlabel=>"boot", :partuuid=>"00000000-0000-0000-0000-000000000000", :parttype=>"c12a7328-f81f-11d2-ba4b-00a0c93ec93b", :devtype=>"part", :fstype=>"vfat",...}
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/shell_helpers/sysutils.rb', line 114 def lsblk(sudo: false) # get devname, mountpoint, (part)label/uuid, (part/dev/fs)type =Run.run_simple("lsblk -l -J -o NAME,MOUNTPOINT,LABEL,UUID,PARTLABEL,PARTUUID,PARTTYPE,TYPE,FSTYPE", fail_mode: :empty, chomp: true, sudo: sudo) require 'json' json=JSON.parse() fs={} json["blockdevices"]&.each do |props| r={} props.each do |k,v| k=k.to_sym k=:devtype if k==:type if k==:name k=:devname v="/dev/#{v}" end r[k]=v unless v.nil? end fs[r[:devname]]=r end fs end |
#make_btrfs_subvolume(dir, check: true) ⇒ Object
makes a btrfs subvolume
450 451 452 453 454 455 456 457 458 |
# File 'lib/shell_helpers/sysutils.rb', line 450 def make_btrfs_subvolume(dir, check: true) if check and dir.directory? raise SysError("Subvolume already exists at #{dir}") if check==:raise warn "Subvolume already exists at #{dir}, skipping..." else SH.sh("btrfs subvolume create #{dir.shellescape}", sudo: true) dir end end |
#make_dir_or_subvolume(dir) ⇒ Object
try to make a subvolume, else fallsback to a dir
461 462 463 464 465 466 467 468 469 470 471 472 |
# File 'lib/shell_helpers/sysutils.rb', line 461 def make_dir_or_subvolume(dir) dir=Pathname.new(dir) return :directory if dir.directory? fstype=stat_filesystem(dir, up: true) if fstype[:fstype]=="btrfs" make_btrfs_subvolume(dir) return :subvol else dir.sudo_mkpath return :directory end end |
#make_fs(fs, check: true) ⇒ Object
make filesystems takes a list of fs infos (where the device is specified like before, via devname, label, ...)
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
# File 'lib/shell_helpers/sysutils.rb', line 412 def make_fs(fs, check: true) fs=fs.values if fs.is_a?(Hash) fs.each do |partfs| dev=SH.find_device(partfs) if dev and (fstype=partfs[:fstype]) opts=partfs[:fsoptions]||[] bin="mkfs.#{fstype.to_s.shellescape}" bin="mkswap" if fstype.to_s=="swap" label=partfs[:label]||partfs[:name] if label labelkey="-L" labelkey="-n" if fstype.to_s=="vfat" opts+=[labelkey, label] end if check diskinfos=blkid(dev, sudo: true) unless diskinfos.dig(dev,:fstype).nil? raise SysError("Device #{dev} already has a filesystem: #{diskinfos[dev]}") if check==:raise warn "Device #{dev} already has a filesystem: #{diskinfos[dev]}" next end end SH.sh("#{bin} #{opts.shelljoin} #{dev.shellescape}", sudo: true) end end end |
#make_partitions(partitions, check: true, partprobe: true) ⇒ Object
@options:
- check => check that no partitions exist first
- partprobe: run partprobe if we made partitions SH.make_partitions( {:parttype=>:boot, :partlength=>"+100M", :fstype=>"vfat", :rel_mountpoint=>"boot", :mountoptions=>["fmask=133"], :slash=> :fstype=>"ext4", :rel_mountpoint=>".", ...})
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/shell_helpers/sysutils.rb', line 354 def make_partitions(partitions, check: true, partprobe: true) partitions=partitions.values if partitions.is_a?(Hash) done=[] disk_partitions=partitions.group_by {|p| p[:disk]} disk_partitions.each do |disk, dpartitions| next if disk.nil? if check partinfos=blkid(disk, sudo: true) # gpt partitions: PTUUID="652121ab-7935-403c-8b87-65a149a415ac" PTTYPE="gpt" # dos partitions: PTUUID="17a4a006" PTTYPE="dos" # others: PTTYPE="PMBR" unless partinfos.empty? raise SysError("Disk #{disk} is not empty: #{partinfos}") if check==:raise warn "Disk #{disk} is not empty: #{partinfos}, skipping..." next end end opts=[] dpartitions.each do |partition| next unless %i(partnum partstart partlength partlabel partattributes parttype).any? {|k| partition.key?(k)} num=partition[:partnum]&.to_i || 0 start=partition[:partstart] || 0 length=partition[:partlength] || 0 name=partition[:partlabel] || partition[:name] attributes=partition[:partattributes] type=partition[:parttype] attributes=2 if type==:boot type=partition_type(type, mode: :hexa) if type.is_a?(Symbol) uuid=partition[:partuuid] alignment=partition[:partalignment] opts += ["-n", "#{num}:#{start}:#{length}"] opts += ["-c", "#{num}:#{name}"] if name opts += ["-t", "#{num}:#{type}"] if type opts += ["-u", "#{num}:#{uuid}"] if uuid opts << "--attributes=#{num}:set:#{attributes}" if attributes opts << ["--set-alignment=#{alignment}"] if alignment end unless opts.empty? Sh.sh!("sgdisk #{opts.shelljoin} #{disk.shellescape}", sudo: true) done << disk end end SH.sh("partprobe #{done.shelljoin}", sudo: true) unless done.empty? or !partprobe done end |
#make_raw_image(name, size = "1G") ⇒ Object
use fallocate to make a raw image
440 441 442 443 444 445 446 447 |
# File 'lib/shell_helpers/sysutils.rb', line 440 def make_raw_image(name, size="1G") raw=Pathname.new(name) raw.touch rawfs=stat_filesystem(raw) raw.chattr("+C") if rawfs[:fstype]=="btrfs" Sh.sh("fallocate -l #{size} #{raw.shellescape}") raw end |
#mount(paths, mkpath: true, abort_on_error: true, sort: true) ⇒ Object
Mount devices on paths
- paths: Array (or Hash) of path => path: "/mnt", mountoptions: [], fstype: "ext4", subvol: ..., device_info where device_info is used to find the device via find_device so can be set via :devname, or uuid label partuuid partlabel parttype
- sort: sort the mountpoints
- abort_on_error: fail if a mount failt
- mkpath: mkpath the mountpoints the paths and a lambda to unmount
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/shell_helpers/sysutils.rb', line 248 def mount(paths, mkpath: true, abort_on_error: true, sort: true) paths=paths.values if paths.is_a?(Hash) paths=paths.select {|p| p[:mountpoint]} # sort so that the mounts are in correct order paths=paths.sort { |p1, p2| Pathname.new(p1[:mountpoint]) <=> Pathname.new(p2[:mountpoint]) } if sort close=lambda do umount(paths, sort: sort) end paths.each do |path| dev=find_device(path) raise SysError.new("Device #{path} not found") unless dev =path[:mountoptions]||[] =.split(',') if .is_a?(String) <<"subvol=#{path[:subvol].shellescape}" if path[:subvol] #options=options.join(',') if options.is_a?(Array) mntpoint=Pathname.new(path[:mountpoint]) mntpoint.sudo_mkpath if mkpath cmd="mount #{(fs=path[:fstype]) && "-t #{fs.shellescape}"} #{.empty? ? "" : "-o #{.join(',').shellescape}"} #{dev.shellescape} #{mntpoint.shellescape}" abort_on_error ? Sh.sh!(cmd, sudo: true) : Sh.sh(cmd, sudo: true) end if block_given? begin yield paths ensure close.call end end return paths, close end |
#parse_blkid(output) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/shell_helpers/sysutils.rb', line 73 def parse_blkid(output) devs={} r=[] convert=lambda do |h| h[:type] && h[:fstype]=h.delete(:type) name=h[:devname] devs[name]=h end output=output.each_line if output.is_a?(String) output.each do |l| l=l.chomp if l.empty? convert.(Export.import_parse(r)) r=[] else r<<l end end convert.(Export.import_parse(r)) unless r.empty? devs end |
#partition_infos(device, sudo: false) ⇒ Object
SH.partition_infos("/dev/sda", sudo: true) => [:partattributes=>"0000000000000004", :partuuid=>"00000000-0000-0000-0000-000000000000", :parttype=>"c12a7328-f81f-11d2-ba4b-00a0c93ec93b", :partattributes=>"0000000000000000", :partuuid=>"f4eef373-0803-4701-bd47-b968c44065a6", :parttype=>"0fc63daf-8483-4772-8e79-3d69d8477de4", :partattributes=>"0000000000000000", :partuuid=>"31b4cd66-39ab-4c5b-a229-d5d2010d53dd", :parttype=>"0fc63daf-8483-4772-8e79-3d69d8477de4"]
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'lib/shell_helpers/sysutils.rb', line 321 def partition_infos(device, sudo: false) parts = Run.run_simple("partx -o NR --show #{device.shellescape}", sudo: sudo) { return nil } infos=[] nums=parts.each_line.count - 1 (1..nums).each do |i| infos[i-1]={} =Run.run_simple("sgdisk -i#{i} #{device.shellescape}", chomp: true, sudo: sudo) .match(/^Partition name: '(.*)'/) do |m| infos[i-1][:partlabel]=m[1] end .match(/^Attribute flags: (.*)/) do |m| infos[i-1][:partattributes]=m[1] end .match(/^Partition unique GUID: (.*)/) do |m| infos[i-1][:partuuid]=m[1].downcase end .match(/^Partition GUID code: (\S*)/) do |m| infos[i-1][:parttype]=m[1].downcase end end infos end |
#partition_type(type, mode: :guid) ⇒ Object
by default give symbol => guid can also give symbol => hexa (mode: :hexa) or hexa/guid => symbol (mode: :symbol)
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/shell_helpers/sysutils.rb', line 291 def partition_type(type, mode: :guid) if mode==:symbol %i(boot swap home x86_root x86-64_root arm64_root arm32_root linux).each do |symb| %i(hexa guid).each do |mode| partition_type(symb, mode: mode) == type.downcase and return symb end end end case type when :boot mode == :hexa ? "ef00" : "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" when :swap mode == :hexa ? "8200" : "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f" when :home mode == :hexa ? "8302" : "933ac7e1-2eb4-4f13-b844-0e14e2aef915" when :x86_root mode == :hexa ? "8303" : "44479540-f297-41b2-9af7-d131d5f0458a" when :"x86-64_root" mode == :hexa ? "8304" : "4f68bce3-e8cd-4db1-96e7-fbcaf984b709" when :arm64_root mode == :hexa ? "8305" : "b921b045-1df0-41c3-af44-4c6f280d3fae" when :arm32_root mode == :hexa ? "8307" : "69dad710-2ce4-4e3c-b16c-21a1d49abed3" when :linux mode == :hexa ? "8300" : "0fc63daf-8483-4772-8e79-3d69d8477de4" end end |
#refresh_blkid_cache ⇒ Object
164 165 166 |
# File 'lib/shell_helpers/sysutils.rb', line 164 def refresh_blkid_cache Sh.sh("blkid", sudo: true) end |
#stat_file(file) ⇒ Object
wrap 'stat' SH.stat_file("mine") => :blocknumber=>0,...
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/shell_helpers/sysutils.rb', line 15 def stat_file(file) require 'time' opts=%w(a b B f F g G h i m n N o s u U w x y z) stats=Run.run_simple("stat --format='#{opts.map{|o| "%#{o}\n"}.join}' #{file.shellescape}", chomp: :lines) r={} r[:access]=stats[0] r[:blocknumber]=stats[1].to_i r[:blocksize]=stats[2].to_i r[:rawmode]=stats[3] r[:filetype]=stats[4] r[:gid]=stats[5].to_i r[:group]=stats[6] r[:hardlinks]=stats[7].to_i r[:inode]=stats[8].to_i r[:mountpoint]=stats[9] r[:filename]=stats[10] r[:quotedfilename]=stats[11] r[:optimalsize]=stats[12] r[:size]=stats[13].to_i r[:uid]=stats[14].to_i r[:user]=stats[15] r[:birthtime] = begin Time.parse(stats[16]) rescue nil end r[:accesstime] = begin Time.parse(stats[17]) rescue nil end r[:changedtime]= begin Time.parse(stats[18]) rescue nil end r[:statustime] = begin Time.parse(stats[19]) rescue nil end r end |
#stat_filesystem(file, up: true) ⇒ Object
wrap stat --file-system SH.stat_filesystem("mine") => fstype=>"btrfs"
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/shell_helpers/sysutils.rb', line 46 def stat_filesystem(file, up: true) if up #output the fs info of the first ascending path that exist # usefull to get infos of the filesystem of a file we want to create # but does not yet exist file=Pathname.new(file) file.ascend.each do |f| return stat_filesystem(f, up: false) if f.exist? end end opts=%w(a b c d f i l n s S T) stats=Run.run_simple("stat --file-system --format='#{opts.map{|o| "%#{o}\n"}.join}' #{file.shellescape}", chomp: :lines) #stats=stats.each_line.map {|l| l.chomp} r={} r[:userfreeblocks]=stats[0].to_i r[:totalblocks]=stats[1].to_i r[:totalnodes]=stats[2].to_i r[:freenodes]=stats[3].to_i r[:freeblocks]=stats[4].to_i r[:fsid]=stats[5] r[:maxlength]=stats[6].to_i r[:name]=stats[7] r[:blocksize]=stats[8].to_i r[:innerblocksize]=stats[9].to_i r[:fstype]=stats[10] r end |
#umount(paths, sort: true) ⇒ Object
278 279 280 281 282 283 284 285 286 |
# File 'lib/shell_helpers/sysutils.rb', line 278 def umount(paths, sort: true) paths=paths.values if paths.is_a?(Hash) paths=paths.select {|p| p[:mountpoint]} paths=paths.sort { |p1, p2| Pathname.new(p1[:mountpoint]) <=> Pathname.new(p2[:mountpoint]) } if sort paths.reverse.each do |path| mntpoint=path[:mountpoint] Sh.sh("umount #{mntpoint.shellescape}", sudo: true) end end |