-
Notifications
You must be signed in to change notification settings - Fork 53
/
Copy pathdu
executable file
·199 lines (150 loc) · 5.46 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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
#!/usr/bin/perl
=begin metadata
Name: du
Description: display disk usage statistics
Author: Greg Hewgill, [email protected]
License: perl
=end metadata
=cut
#
# Perl Power Tools - du
# Greg Hewgill <[email protected]> 1999-03-07
use strict;
use File::Spec;
use Getopt::Std;
use constant EX_SUCCESS => 0;
use constant EX_FAILURE => 1;
use vars qw($opt_H $opt_L $opt_P $opt_a $opt_c $opt_k $opt_l $opt_r $opt_s $opt_x);
use vars qw(%inodes $depth $blocksize $grandtotal $filesystem);
%inodes = (); # A record of where we've been
$depth = 0; # Current recursion depth
$blocksize = 512; # Default block size
$grandtotal = 0; # Total of all command line argument totals
$filesystem = 0; # Current file system (used for -x processing)
# Process command line options
getopts('HLPacklrsx') or usage();
$blocksize = $ENV{'BLOCKSIZE'} if defined $ENV{'BLOCKSIZE'};
$blocksize = 1024 if $opt_k;
if ($blocksize =~ m/[^0-9]/ || $blocksize == 0) {
warn "$0: unexpected block size: $blocksize\n";
exit EX_FAILURE;
}
if ($opt_a && $opt_s) {
warn "$0: cannot both summarize and show all entries\n";
usage();
}
# Default to traversing current directory if no files specified
unless (@ARGV) {
push @ARGV, '.';
}
my $rc = EX_SUCCESS;
foreach (@ARGV) {
%inodes = (); # clear this at the start of each traversal
$grandtotal += traverse($_);
}
print "$grandtotal\ttotal\n" if $opt_c;
exit $rc;
sub traverse {
my $fn = $_[0];
my $total = 0;
local $depth = $depth + 1;
my @s = ($opt_L || $opt_H && $depth == 1) ? stat $fn : lstat $fn;
unless (@s) {
warn "$0: cannot access '$fn': $!\n";
$rc = EX_FAILURE;
return 0;
}
# Check for cross-filesystem traversals (-x option)
if ($depth == 1) {
$filesystem = $s[0];
} elsif ($opt_x && $s[0] != $filesystem) {
return 0;
}
if ($s[1] && !$opt_l) {
# Check to see whether we've been here before (dev/inode is unique)
if ($inodes{$s[0]}{$s[1]}) {
return 0;
}
$inodes{$s[0]}{$s[1]} = 1;
}
# For regular files or links, tally them up
unless (-d _) {
$total = int(($s[7] + $blocksize-1) / $blocksize);
print "$total\t$fn\n" if $opt_a || $depth == 1;
return $total;
}
# Do recursion
my $dh;
if (opendir $dh, $fn) {
foreach (readdir $dh) {
next if $_ eq '.' or $_ eq '..';
my $subdir = File::Spec->catfile($fn, $_);
$total += traverse($subdir);
}
closedir $dh;
print "$total\t$fn\n" unless $opt_s;
} else {
warn "$0: could not read directory $fn: $!\n";
$rc = EX_FAILURE;
}
print "$total\t$fn\n" if $opt_s && $depth == 1;
return $total;
}
sub usage {
print "usage: $0 [-H | -L | -P] [-a | -s] [-cklrx] [file ...]\n";
exit EX_FAILURE;
}
=head1 NAME
du - display disk usage statistics
=head1 SYNOPSIS
B<du> [B<-H> | B<-L> | B<-P>] [B<-a> | B<-s>] [B<-cklrx>] [I<file> ...]
=head1 DESCRIPTION
The B<du> utility displays the file system block usage for each file argument
and for each directory in the file hierarchy rooted in each directory
argument. If no file is specified, the block usage of
the hierarchy rooted in the current directory is displayed.
The options are as follows:
B<-H> Symbolic links on the command line are followed. (Symbolic links
encountered in the tree traversal are not followed.)
B<-L> All symbolic links are followed.
B<-P> No symbolic links are followed.
B<-a> Display an entry for each file in the file hierarchy.
B<-k> By default, du displays the number of blocks as the number of
512-byte blocks. If the B<-k> flag is
specified, the number displayed is the number of 1024-byte
blocks. Partial numbers of blocks are rounded up.
B<-c> Display the grand total after all the arguments have been processed.
B<-l> Count the size of all files, even if they have appeared already
in another hard link.
B<-s> Display only the grand total for the specified files.
B<-r> Generate messages about directories that cannot be read, files
that cannot be opened, and so on. This is the default case.
This option exists solely for conformance with X/Open Portability
Guide Issue 4 (``XPG4'').
B<-x> Filesystem mount points are not traversed.
B<du> counts the storage used by symbolic links and not the files they
reference unless the B<-H> or B<-L> option is specified. If either the B<-H>
or B<-L> options are specified, storage used by any symbolic links which are
followed is not counted or displayed.
Files having multiple hard links are counted (and displayed) a single
time per B<du> execution.
=head1 ENVIRONMENT
If the environment variable BLOCKSIZE is set, and the B<-k> option is not
specified, the block counts will be displayed in units of that size block.
=head1 BUGS
The number of blocks reported is based on the size of the file. This may
or may not reflect the actual number of blocks allocated by the file system
for the file.
B<du> will skip files it shouldn't if the underlying file system does
not support inodes, and does not always place 0 in the inode field of a
stat(2) call. In this case B<-l> can be specified to skip the inode check
and always list all files.
=head1 HISTORY
A B<du> command appeared in Version 6 AT&T UNIX.
=head1 AUTHOR
Greg Hewgill <[email protected]> 1999-03-07
=head1 COPYRIGHT and LICENSE
This program is Copyright (c) by Greg Hewgill 1999.
This program is free and open software. You may use, copy, modify,
distribute, and sell this program (and any modified variants) in any
way you wish, provided you do not restrict others from doing the same.