add proper error handling for all final exec calls
[hband-tools.git] / user-tools / dfbar
blob6a0b0c74456ae55219843bbc9a90e43aa90a645c
1 #!/usr/bin/env perl
3 use Data::Dumper;
4 use Getopt::Long qw/:config no_ignore_case/;
6 # defaults
7 $divisor = 1024;
8 $useNBH = 1;
9 @suff = split/,/,"b,K,M,G,T,P";
10 %mult = map { $_ => $n++ } @suff;
11 %patt = ( used=>"=", free=>"ยท", );
12 $show_total_size = 0;
13 $Help = "$0 [--relative|-r | --barrelative|-br | --show-total-size|-t | --used=* | --free=. | --divisor=1024 | --si | --human|-h]\n";
16 # commandline parameters
17 GetOptions(
18 "relative" => \$mode{"relative"},
19 "br|barrelative" => sub { $mode{"barrelative"} = $mode{"relative"} = 1 },
20 "used=s" => \$patt{"used"},
21 "free=s" => \$patt{"free"},
22 "divisor=i" => \$divisor,
23 "si" => sub { $divisor = 1000; },
24 "h|human!" => \$useNBH,
25 "t|show-total-size" => \$show_total_size,
26 "help" => sub { print $Help; exit; },
27 ) or die $Help;
29 $dfdirs = join ' ', @ARGV;
32 *hsize = ($useNBH and eval "use Number::Bytes::Human 'format_bytes'; 1") ?
33 sub {
34 return format_bytes($_[0] * $divisor ** $mult{$_[1]}, bs=>$divisor);
35 } :
36 sub {
37 $x=$_[0];
38 $suffi = $mult{$_[1]};
39 while($x >= $divisor and $suffi < $#suff) {
40 $x/=$divisor;
41 $suffi++;
43 return sprintf "%0.2f%s", $x, $suff[$suffi];
46 $COLUMNS = $ENV{"COLUMNS"} || join "", grep {/\d/} (split //, `tput cols`);
47 if(-t 0) {
48 @lines = split /[\n\r]+/, `df -kPT $dfdirs`;
50 else {
51 print STDERR "Enter 'df -kPT' lines...\n";
52 @lines = <>;
54 shift @lines; # skip header
57 # rootfs rootfs 976762584 845002520 128488984 87% /
58 use constant {DFCOL_FS => 0, DFCOL_MP => 6, DFCOL_TOTAL => 2, DFCOL_FREE => 4, DFCOL_PERCENT => 5,};
59 # fs | mountpoint | total size human-readable | free space human-readable | used% | total size in K
60 use constant {COL_FS => 0, COL_MP => 1, COL_SIZE => 2, COL_PERCENT => 3, COL_TOTAL => 4,};
62 for(@lines) {
63 @_ = split /\s+/;
64 my $used_percent = ($_[DFCOL_PERCENT] =~ /^(\d+)/)[0];
65 #my $free_percent = sprintf "%d", $_[DFCOL_FREE] * 100 / $_[DFCOL_TOTAL];
66 push @table, [$_[DFCOL_FS], $_[DFCOL_MP], $show_total_size ? hsize($_[DFCOL_TOTAL],"K") : hsize($_[DFCOL_FREE],"K"), $used_percent, $_[DFCOL_TOTAL]];
69 # calculate width of table cells
70 for my $i (COL_FS..COL_SIZE) {
71 $maxfield[$i] = length((sort {length $$b[$i] <=> length $$a[$i]} @table)[0][$i]);
73 # reminder space for percetange bars
74 $barfull = ($COLUMNS-($maxfield[COL_FS]+1+$maxfield[COL_MP]+1+3+$maxfield[COL_SIZE]+1));
75 # largest disk
76 $maxdisk = (sort {$$b[COL_TOTAL] <=> $$a[COL_TOTAL]} @table)[0][COL_TOTAL];
80 for(@table) {
81 @row = @$_;
82 $ratio = $barratio = 1;
83 $freepatt = $patt{"free"};
84 $usedpatt = $patt{"used"};
85 if($mode{"relative"}) {
86 $ratio = sprintf "%0.4f", $row[COL_TOTAL]/$maxdisk;
87 if($mode{"barrelative"}) {
88 $barratio = $ratio;
90 # do not show free space if it isnt relative to other bars in relative mode
91 else { $freepatt = " " }
93 $used = int($barfull * $ratio * $row[COL_PERCENT] * 0.01);
94 $free = int($barfull * $barratio) - $used;
95 $pad = $barfull - int($barfull * $barratio);
97 $format = sprintf "%%-%ds %%-%ds [%%s%%s]%%%ds %%%ds\n", $maxfield[0], $maxfield[1], $pad, $maxfield[2];
98 printf $format, $row[COL_FS], $row[COL_MP], $usedpatt x $used, $freepatt x $free, "", $row[COL_SIZE];
101 __END__
103 =pod
105 =head1 NAME
107 dfbar - Display disk space usage with simple bar chart (as reported by df(1))
109 =cut