Subject: Suggestion for changes to df(1) and du(1)
To: None <tech-userlevel@netbsd.org>
From: Tomas Svensson <tsn@gbdev.net>
List: tech-userlevel
Date: 11/19/2001 03:44:36
Hi,
Does anyone have an opinion about adding the flag -h to df(1) and du(1)?
It would be to print the statistics in a more "human-readable" and
compact style.
Example output:
Filesystem Size Used Avail Capacity Mounted on
/dev/wd0a 97M 31M 61M 33% /
/dev/wd0e 97M 4.7M 88M 5% /var
/dev/wd0g 2.8G 1.5G 1.2G 54% /usr
/dev/wd0f 97M 1.0K 92M 0% /tmp
/dev/wd0h 1.8G 297M 1.4G 17% /home
/dev/fd0a 1.4M 636K 787K 44% /mnt
FreeBSD/OpenBSD and GNU fileutils support this flag already, but does
anyone know if this flag would violate POSIX or SUS?
Patches for df including the manpage included (just a draft), I also
added -g (display statistics in gigabyte block counts) just for
completeness.
-Tomas
diff -u df1/df.1 df/df.1
--- df1/df.1 Sun Nov 18 23:08:29 2001
+++ df/df.1 Sun Nov 18 22:56:15 2001
@@ -41,7 +41,7 @@
.Nd display free disk space
.Sh SYNOPSIS
.Nm
-.Op Fl aiklmnP
+.Op Fl aghiklmnP
.Op Fl t Ar type
.Op Ar file | Ar file_system ...
.Sh DESCRIPTION
@@ -51,7 +51,7 @@
or on the file system of which
.Ar file
is a part.
-Values are displayed in 512-byte per block block counts.
+Values are displayed in 512-byte per block counts.
If neither a file or a
.Ar file_system
operand is specified,
@@ -74,22 +74,26 @@
Show all filesystems. By default only filesystems mounted with the
.Dv MNT_IGNORE
flag clear are shown.
+.It Fl g
+Use 1073741824-byte (gigabyte) block counts rather than the default. This
+overrides the BLOCKSIZE specification from the environment.
+.It Fl h
+Display sizes in a more "human-readable" and compact form. Use unit suffixes:
+Byte, Kilobyte, Megabyte, Gigabyte and Terabyte in order to reduce the number
+of digits to four or less.
.It Fl i
Include statistics on the number of free inodes.
.It Fl k
-By default, all sizes are reported in 512-byte block counts.
-The
-.Fl k
-option causes the numbers to be reported in kilobyte (1024 bytes) counts.
+Use 1024-byte (kilobyte) block counts rather than the default. This overrides
+the BLOCKSIZE specification from the environment.
.It Fl l
Display statistics only about mounted file systems with the
.Dv MNT_LOCAL
flag set. If a non-local file system is given as an argument, a
warning is issued and no information is given on that file system.
.It Fl m
-The
-.Fl m
-option causes the numbers to be reported in megabyte (1024*1024 bytes) counts.
+Use 1048576-byte (megabyte) block counts rather than the default. This
+overrides the BLOCKSIZE specification from the environment.
.It Fl n
Print out the previously obtained statistics from the file systems.
This option should be used if it is possible that one or more
@@ -146,6 +150,8 @@
If the environment variable
.Ev BLOCKSIZE
is set, and the
+.Fl g
+.Fl h
.Fl k
and
.Fl m
diff -u df1/df.c df/df.c
--- df1/df.c Sun Nov 18 23:08:29 2001
+++ df/df.c Sun Nov 18 17:59:27 2001
@@ -62,6 +62,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -72,6 +73,7 @@
int main(int, char *[]);
int bread(off_t, void *, int);
char *getmntpt(char *);
+void prthuman(double);
void prtstat(struct statfs *, int);
int ufs_df(char *, struct statfs *);
int selected(const char *);
@@ -79,7 +81,7 @@
long regetmntinfo(struct statfs **, long);
void usage(void);
-int aflag, iflag, kflag, lflag, mflag, nflag, Pflag;
+int aflag, gflag, hflag, iflag, kflag, lflag, mflag, nflag, Pflag;
char **typelist = NULL;
struct ufs_args mdev;
@@ -92,11 +94,17 @@
int ch, i, maxwidth, width;
char *mntpt;
- while ((ch = getopt(argc, argv, "aiklmnPt:")) != -1)
+ while ((ch = getopt(argc, argv, "aghiklmnPt:")) != -1)
switch (ch) {
case 'a':
aflag = 1;
break;
+ case 'g':
+ gflag = 1;
+ break;
+ case 'h':
+ hflag = 1;
+ break;
case 'i':
iflag = 1;
break;
@@ -326,6 +334,41 @@
(num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
/*
+ * Print sizes in a more human-readable and compact form.
+ */
+void
+prthuman(double bytes)
+{
+ double abytes;
+ char unit;
+
+ if (bytes == 0)
+ (void)printf(" 0B");
+ else {
+ abytes = fabs(bytes);
+ if (abytes < 1024)
+ unit = 'B';
+ else if (abytes < 1024 * 1024ULL) {
+ unit = 'K';
+ bytes /= 1024;
+ } else if (abytes < 1024 * 1024 * 1024ULL) {
+ unit = 'M';
+ bytes /= 1024 * 1024;
+ } else if (abytes < 1024 * 1024 * 1024 * 1024ULL) {
+ unit = 'G';
+ bytes /= 1024 * 1024 * 1024ULL;
+ } else {
+ unit = 'T';
+ bytes /= 1024 * 1024 * 1024 * 1024ULL;
+ }
+ if (bytes > 10)
+ (void)printf(" %5.0f%c", bytes, unit);
+ else
+ (void)printf(" %5.1f%c", bytes, unit);
+ }
+}
+
+/*
* Print out status about a filesystem.
*/
void
@@ -340,19 +383,30 @@
if (maxwidth < 11)
maxwidth = 11;
if (++timesthrough == 1) {
- if (kflag) {
- blocksize = 1024;
- header = Pflag ? "1024-blocks" : "1K-blocks";
- headerlen = strlen(header);
- } else if (mflag) {
- blocksize = 1024 * 1024;
- header = Pflag ? "1048576-blocks" : "1M-blocks";
- headerlen = strlen(header);
- } else
- header = getbsize(&headerlen, &blocksize);
- (void)printf("%-*.*s %s Used %9s Capacity",
- maxwidth, maxwidth, "Filesystem", header,
- Pflag ? "Available" : "Avail");
+ if (hflag)
+ (void)printf("%-*.*s Size Used Avail Capacity",
+ maxwidth, maxwidth, "Filesystem");
+ else {
+ if (kflag) {
+ blocksize = 1024;
+ header = Pflag ? "1024-blocks" : "1K-blocks";
+ headerlen = strlen(header);
+ } else if (mflag) {
+ blocksize = 1024 * 1024;
+ header = Pflag ? "1048576-blocks" :
+ "1M-blocks";
+ headerlen = strlen(header);
+ } else if (gflag) {
+ blocksize = 1024 * 1024 * 1024;
+ header = Pflag ? "1073741824-blocks" :
+ "1G-blocks";
+ headerlen = strlen(header);
+ } else
+ header = getbsize(&headerlen, &blocksize);
+ (void)printf("%-*.*s %s Used %9s Capacity",
+ maxwidth, maxwidth, "Filesystem", header,
+ Pflag ? "Available" : "Avail");
+ }
if (iflag)
(void)printf(" iused ifree %%iused");
(void)printf(" Mounted on\n");
@@ -360,10 +414,15 @@
(void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
used = sfsp->f_blocks - sfsp->f_bfree;
availblks = sfsp->f_bavail + used;
- (void)printf(" %*ld %8ld %9ld", headerlen,
- fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
- fsbtoblk(used, sfsp->f_bsize, blocksize),
- fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
+ if (hflag) {
+ prthuman((double)sfsp->f_blocks * (double)sfsp->f_bsize);
+ prthuman((double)used * (double)sfsp->f_bsize);
+ prthuman((double)sfsp->f_bavail * (double)sfsp->f_bsize);
+ } else
+ (void)printf(" %*ld %8ld %9ld", headerlen,
+ fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
+ fsbtoblk(used, sfsp->f_bsize, blocksize),
+ fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
(void)printf("%7s",
availblks == 0 ? full : strpct((u_long)used, (u_long)availblks, 0));
if (iflag) {
@@ -460,7 +519,7 @@
{
(void)fprintf(stderr,
- "Usage: %s [-aiklmnP] [-t type] [file | file_system ...]\n",
+ "Usage: %s [-aghiklmnP] [-t type] [file | file_system ...]\n",
getprogname());
exit(1);
/* NOTREACHED */