Since the du command used when the capacity is full is difficult to use, I tried wrapping it with ruby

Conclusion

I made a script that wraps the du command with ruby.

Create the name ʻexpand.rb`, paste the script below, and execute it as follows.

# ruby expand.rb (The path you want to find)
$ ruby expand_du.rb /var/lib/
    7GB /var/lib/
    3GB /var/lib/jenkins
    2GB /var/lib/docker
    1GB /var/lib/mysql
    ...
    4KB /var/lib/mysql-files
du_-k_--max-depth_1_var_lib__20200516231438.Saved in log

Scripts (github)

#How to use
# ruby expand_du.rb path
#Example: ruby expand_du.rb ~
#
#effect
# -Execute the du command for the path
# -Output execution result to standard output and file
#
#argument
# -path:Target path to execute the du command

require 'rbconfig'

def main(target_path)
  return puts "ArgumentError:Please put the path as an argument" if target_path.nil?

  max_depth_option_str = if os == :macosx
    "-d"
  else
    "--max-depth"
  end

  exec_command = "du -k #{max_depth_option_str} 1 #{target_path}"
  du_result_str = `#{exec_command}`

  return if du_result_str.empty?

  output_disksizes(du_result_str, exec_command)
end

def output_disksizes(du_result_str, exec_command)
  disk_usages = du_result_str
                  .split("\n")
                  .map{|du_result| DiskUsage.new(du_result)}
                  .sort{|x, y| x.size <=> y.size}.reverse

  output_filename = "#{exec_command.gsub(/( |\/){1,}/, "_")}_#{Time.new.strftime("%Y%m%d%H%M%S")}.log"
  output_file = File.open(output_filename, "w")

  disk_usages.each do |disk_usage|
    puts disk_usage.to_s
    output_file.puts(disk_usage.to_s)
  end

  output_file.close
  puts "#{output_filename}Saved in"
end

class DiskUsage
  attr_reader :size, :path
  def initialize(du_result_line)
    du_result_params = du_result_line.split(" ").map(&:strip)
    @size = du_result_params[0].to_i
    @humanreadable_size, @humanreadable_unit = calc_humanreadable_size
    @path = du_result_params[1]
  end

  def to_s
    #NOTE Specify 5 digits for the time being. Increase when needed
    "#{sprintf("%5d" % @humanreadable_size)}#{@humanreadable_unit} #{@path}"
  end

  def humanreadable_size_with_unit
    "#{@humanreadable_size}#{@humanreadable_unit}"
  end

  private

  def calc_humanreadable_size
    return [@size, "KB"] if mb_size < 1
    return [mb_size, "MB"] if gb_size < 1
    return [gb_size, "GB"] if tb_size < 1
    [tb_size, "TB"]
  end

  def kb_size
    @size
  end

  def mb_size
    kb_size.fdiv(1024).round(1)
  end

  def gb_size
    mb_size.fdiv(1024).round(1)
  end

  def tb_size
    gb_size.fdiv(1024).round(1)
  end
end

def os
  case RbConfig::CONFIG['host_os']
  when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
    :windows
  when /darwin|mac os/
    :macosx
  when /linux/
    :linux
  when /solaris|bsd/
    :unix
  else
    :unknown
  end
end

Background

When your rental server or Mac is full, you'll want to know which folder is the cause.

Therefore, if you are using a Mac, you can see the storage usage status, and even if you are using a rental server, you can see how much you are using with the df command. However, I can only understand the whole thing and not know which folder is the cause.

Therefore, the du command can be used by those who can use the terminal (the ls command is also a candidate, but the ls command knows the size of the file directly under it, but not how big the folder is).

However, this du command is a bit unsatisfactory, probably because it is a UNIX command.

Sorting is not good

To make it easier to read, I use the sort command with the -h option to sort the sizes in descending order, but then 5KB comes above 4GB. I can't help because I'm only looking at the numbers.

It's a hassle to hit twice to record

If you use du, it will output the result to the standard output, but after you do, you will want to record the result. You can output the file from the beginning, but it is troublesome to output the file and then cat. If you devise a command, it will be output to both a file and standard output, but when you need the du command, you are usually in a hurry, so I wanted to do it easily.

Script features

The script that solved the problem above is the first script posted.

The features are as follows.

――It sorts after considering the unit --It outputs both standard output and file (& outputs with a file name that shows which folder was searched)

I made it completely for myself, but if anyone is having trouble with the same thing, please use it.

Recommended Posts

Since the du command used when the capacity is full is difficult to use, I tried wrapping it with ruby
Since the Rspec command is troublesome, I tried to make it possible to execute Rspec with one Rake command
When I try to use the AWS SDK with Ruby + Lambda, `sam local` is messed up.
I tried to make full use of the CPU core in Ruby
When I tried to use a Wacom tablet with ubuntu 20.04, I didn't recognize it.
When importing CSV with Rails, it was really easy to use the nkf command
I tried to solve the problem of "multi-stage selection" with Ruby
[Ruby] This is the solution. When should I use instance variables?
I tried to summarize the methods used
[Ruby] I tried to diet the if statement code with the ternary operator
I tried to solve the tribonacci sequence problem in Ruby, with recursion.
Since the docker-desktop preview for m1 came out, I tried to face it with my macbook pro 15inch
I tried to get the distance from the address string to the nearest station with ruby
Since the argument of link_to is nil (null) and an unexpected link was generated, I tried to verify it
I tried to summarize the points to consider when acquiring location information with the iOS application ③
[Beginner's point of view] I tried to solve the FizzBuzz problem "easily" with Ruby!
I tried to summarize the points to consider when acquiring location information with the iOS application ①
When I tried to support IPv6 easily with Docker-proxy, I couldn't do it before I knew it.
I tried to summarize the points to consider when acquiring location information with the iOS application ②
I tried to investigate the mechanism of Emscripten by using it with the Sudoku solver
A warning is displayed when trying to use a huge integer with the special variables $ 1, $ 2, $ 3 ...
I tried to organize the cases used in programming
I tried to reduce the capacity of Spring Boot
I used jnr-ffi (made it easier to use, etc.)
roman numerals (I tried to simplify it with hash)
It is difficult to use the empty string or date of DBUnit, so fix it and use it.
I tried to solve the Ruby karaoke machine problem (there is an example of the answer)
When I tried to scroll automatically with JScrollBar, the event handler was drawn only once.
I tried to solve the Ruby bonus drink problem (there is an example of the answer)
Since the reading of JdbcCodeList of TERASOLUNA is slow, I tried to register multiple at once.
When I tried to run Azure Kinect DK with Docker, it was blocked by EULA
Why can I use the rails command installed with gem? ??
I tried to increase the processing speed with spiritual engineering
I tried to summarize the basic grammar of Ruby briefly
I tried to automate LibreOffice Calc with Ruby + PyCall.rb (Ubuntu 18.04)
When I used Slick on Rails, it competed with Turbolinks.
I tried upgrading from CentOS 6.5 to CentOS 7 with the upgrade tool
I want to pass the startup command to postgres with docker-compose.
I tried to solve the Ruby bingo card creation problem (there is an example of the answer)
Is it easy for the user to use when implementing general-purpose functions? Let's be aware of
When I tried to run my own service, it failed, so I screwed it into the task scheduler
Memorandum: When I tried TensorFlow with Tribuo, it didn't work, so I went on a journey to find the head family and lost.
I tried DI with Ruby
Rbenv command to use Ruby
When requested access to the resource is denied when pushing with Docker
I tried to build the environment of PlantUML Server with Docker
I got an IllegalAccessError when trying to use PowerMock with JUnit
[Ruby] Tonight, I tried to summarize the loop processing [times, break ...]
I tried to implement the image preview function with Rails / jQuery
I tried to translate the error message when executing Eclipse (Java)
I tried to understand how the rails method "redirect_to" is defined
I tried to reimplement Ruby Float (arg, exception: true) with builtin
I tried to check the operation of gRPC server with grpcurl
I tried to understand how the rails method "link_to" is defined
I tried to make Numeron which is not good in Ruby
I want to download a file on the Internet using Ruby and save it locally (with caution)
I tried to figure out the flow when performing image analysis with Vision Framework and Core ML
I tried running gRPC's Quick Start (Kotlin version), but it was difficult to read the Gradle script.