-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathtree_size.py
executable file
·97 lines (81 loc) · 3.13 KB
/
tree_size.py
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
95
96
97
#!/usr/bin/env python
# From Python Cookbook
# http://my.safaribooksonline.com/book/programming/python/0596001673/files/pythoncook-chp-4-sect-24
# v 1.1 modified the original to fix the sizing bug. The script linked above
# would calculate size in bytes, regardless of the parameter passed to it.
# essentially does the same thing as 'du --max-depth=X -h <path>'
import os
from os.path import *
class DirSizeError(Exception): pass
def dir_size(start, follow_links=0, start_depth=0, max_depth=0, skip_errs=0):
# Get a list of all names of files and subdirectories in directory start
try: dir_list = os.listdir(start)
except:
# If start is a directory, we probably have permission problems
if os.path.isdir(start):
raise DirSizeError('Cannot list directory %s'%start)
else: # otherwise, just re-raise the error so that it propagates
raise
total = 0L
for item in dir_list:
# Get statistics on each item--file and subdirectory--of start
path = join(start, item)
try: stats = os.stat(path)
except:
if not skip_errs:
raise DirSizeError('Cannot stat %s'%path)
# The size in bytes is in the seventh item of the stats tuple, so:
total += stats[6]
# recursive descent if warranted
if isdir(path) and (follow_links or not islink(path)):
bytes = dir_size(path, follow_links, start_depth+1, max_depth)
total += bytes
if max_depth and (start_depth < max_depth):
print_path(path, bytes, units)
return total
def print_path(path, bytes, units):
if units == 'k':
print '%-8ld%s' % (bytes / 1024, path)
elif units == 'm':
print '%-5ld%s' % (bytes / 1024 / 1024, path)
else:
print '%-11ld%s' % (bytes, path)
def usage (name):
print "usage: %s [-bkLm] [-d depth] directory [directory...]" % name
print '\t-b\t\tDisplay in Bytes (default)'
print '\t-k\t\tDisplay in Kilobytes'
print '\t-m\t\tDisplay in Megabytes'
print '\t-L\t\tFollow symbolic links (meaningful on Unix only)'
print '\t-d, --depth\t# of directories down to print (default = 0)'
if __name__=='__main__':
# When used as a script:
import string, sys, getopt
units = 'b'
follow_links = 0
depth = 0
try:
opts, args = getopt.getopt(sys.argv[1:], "bkLmd:", ["depth="])
except getopt.GetoptError:
usage(sys.argv[0])
sys.exit(1)
for o, a in opts:
if o == '-b': units = 'b'
elif o == '-k': units = 'k'
elif o == '-L': follow_links = 1
elif o == '-m': units = 'm'
elif o in ('-d', '--depth'):
try: depth = int(a)
except:
print "Not a valid integer: (%s)" % a
usage(sys.argv[0])
sys.exit(1)
if len(args) < 1:
print "No directories specified"
usage(sys.argv[0])
sys.exit(1)
else:
paths = args
for path in paths:
try: bytes = dir_size(path, follow_links, 0, depth)
except DirSizeError, x: print "Error:", x
else: print_path(path, bytes, units)