-
Notifications
You must be signed in to change notification settings - Fork 5
/
DU
executable file
·94 lines (86 loc) · 1.9 KB
/
DU
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
42
43
44
45
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/ruby
def human(size)
units = 'kMGTPEZY'
unit_index = -1
size *= 10
while size >= 10000 && unit_index < units.size - 1
unit_index += 1
size /= 1000
end
unit = unit_index >= 0 ? units[unit_index] : ''
if unit_index >= 0 && size < 100
return '%d.%d%s' % [size / 10, size % 10, unit]
else
return '%d%s' % [size / 10, unit]
end
end
def parse_line(line)
size, name = line.split(' ', 2)
size = size.to_i
[size, name.chomp]
end
def is_already_counted(name, seen_prefixes)
while name.b =~ /\/[^\/]+$/n
name = $`
if seen_prefixes[name]
return true
end
end
return false
end
mu = Mutex.new
started = false
tmpfile = '/tmp/du.tmp'
TOP_N = 3
if true
thread = Thread.new do
while true
sleep 0.1
next if !File.exist?(tmpfile)
mu.synchronize do
Thread.exit if started
dirs = 0
total = 0
tops = []
seen_prefixes = {}
IO.popen("sort -nr #{tmpfile}") do |pipe|
pipe.each do |line|
size, name = parse_line(line)
dirs += 1
if !is_already_counted(name, seen_prefixes)
total += size
end
seen_prefixes[name] = true
if tops.size < TOP_N
tops << "#{name}:#{human(size)}"
end
end
end
Thread.exit if started
msg = "\r#{human(total)}/#{human(dirs)} [#{tops * ' '}]"
if msg.size > 79
msg = msg[0,79]
else
msg = msg.ljust(79)
end
STDERR.print msg
end
end
end
end
open('/tmp/du.out', 'w') do |of|
IO.popen("du -b #{ARGV[0]} | tee #{tmpfile} | sort -n") do |pipe|
pipe.each do |line|
mu.synchronize do
started = true
end
size, name = parse_line(line)
line = "#{human(size)} #{name}"
of.puts line
puts line
end
end
end
if thread
thread.join
end