Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Nov 1999 23:04:36 -0500
From:      matt@csis.gvsu.edu
To:        freebsd-hackers@freebsd.org
Subject:   Human readable df
Message-ID:  <19991129230436.A6501@badmofo>

next in thread | raw e-mail | index | archive | help
Not sure if -hackers is the place for this, but here goes.

Here's a patch to add -h flag to df to produce human readable
output. This makes it easier to read if the disk is big.
Example:

[badmofo@/home/matt] df -h
Filesystem    Size   Used    Avail Capacity Mounted on
/dev/wd0s1a   722M    20M   644M     3%     /
/dev/wd0s2h   9.9G   4.4G   4.8G    48%     /usr
procfs        4.0K   4.0K     0B   100%     /proc
....

Code merged from OpenBSD and added to FreeBSD-STABLE. 

[badmofo@/usr/src/bin/df] diff -u df df~
diff -u df/df.1 df~/df.1
--- df/df.1	Sun Aug 29 10:12:14 1999
+++ df~/df.1	Mon Nov 29 22:57:01 1999
@@ -40,7 +40,7 @@
 .Nd display free disk space
 .Sh SYNOPSIS
 .Nm df
-.Op Fl ikn
+.Op Fl hikn
 .Op Fl t Ar type
 .Op Ar file | Ar filesystem ...
 .Sh DESCRIPTION
@@ -59,6 +59,10 @@
 .Pp
 The following options are available:
 .Bl -tag -width Ds
+.It Fl h
+"Human-readable" output. Use unit suffixes: Byte, Kilobyte, Megabyte,
+Gigabyte, Terabyte, Petabyte, Exabyte 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
diff -u df/df.c df~/df.c
--- df/df.c	Sun Aug 29 10:12:15 1999
+++ df~/df.c	Mon Nov 29 22:57:01 1999
@@ -59,11 +59,14 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
+typedef enum { NONE = 0, KILO, MEGA, GIGA, TERA, PETA /* , EXA */ } unit_t;
+
 int	  checkvfsname __P((const char *, char **));
 char	**makevfslist __P((char *));
 long	  regetmntinfo __P((struct statfs **, long, char **));
@@ -71,9 +74,12 @@
 char	 *getmntpt __P((char *));
 void	  prtstat __P((struct statfs *, int));
 int	  ufs_df __P((char *, int));
+unit_t unit_adjust __P((double *));
+void	prthumanval __P((double));
+void	prthuman __P((struct statfs *, long));
 void	  usage __P((void));
 
-int	iflag, nflag;
+int	iflag, nflag, hflag;
 struct	ufs_args mdev;
 
 int
@@ -88,8 +94,11 @@
 	char *mntpt, *mntpath, **vfslist;
 
 	vfslist = NULL;
-	while ((ch = getopt(argc, argv, "iknt:")) != -1)
+	while ((ch = getopt(argc, argv, "hiknt:")) != -1)
 		switch (ch) {
+		case 'h':
+			hflag = 1;
+			break;
 		case 'i':
 			iflag = 1;
 			break;
@@ -267,20 +276,26 @@
 	if (maxwidth < 11)
 		maxwidth = 11;
 	if (++timesthrough == 1) {
-		header = getbsize(&headerlen, &blocksize);
-		(void)printf("%-*.*s %s     Used    Avail Capacity",
+		if(hflag)
+			header = "  Size";
+		else
+			header = getbsize(&headerlen, &blocksize);
+			(void)printf("%-*.*s %s   Used    Avail Capacity",
 		    maxwidth, maxwidth, "Filesystem", header);
 		if (iflag)
 			(void)printf(" iused   ifree  %%iused");
-		(void)printf("  Mounted on\n");
+		(void)printf(" Mounted on\n");
 	}
 	(void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
 	used = sfsp->f_blocks - sfsp->f_bfree;
 	availblks = sfsp->f_bavail + used;
-	(void)printf(" %*ld %8ld %8ld", 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(sfsp, used);
+	else 
+		(void)printf(" %*ld %8ld %8ld", 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(" %5.0f%%",
 	    availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
 	if (iflag) {
@@ -290,7 +305,67 @@
 		   inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
 	} else
 		(void)printf("  ");
-	(void)printf("  %s\n", sfsp->f_mntonname);
+	(void)printf("   %s\n", sfsp->f_mntonname);
+}
+
+/*
+ * "human-readable" output: use 3 digits max.--put unit suffixes at
+ * the end.  Makes output compact and easy-to-read esp. on huge disks.
+ */
+
+unit_t
+unit_adjust(val)
+	double *val;
+{
+	double abval;
+	unit_t unit;
+
+	abval = fabs(*val);
+	if (abval < 1024)
+		unit = NONE;
+	else if (abval < 1048576ULL) {
+		unit = KILO;
+		*val /= 1024;
+	} else if (abval < 1073741824ULL) {
+		unit = MEGA;
+		*val /= 1048576;
+	} else if (abval < 1099511627776ULL) {
+		unit = GIGA;
+		*val /= 1073741824ULL;
+	} else if (abval < 1125899906842624ULL) {
+		unit = TERA;
+		*val /= 1099511627776ULL;
+	} else if (abval < 1152921504606846976ULL) {
+		unit = PETA;
+		*val /= 1125899906842624ULL;
+	}
+	return (unit);
+}
+
+void
+prthumanval(bytes)
+	double bytes;
+{
+	unit_t unit;
+
+	unit = unit_adjust(&bytes);
+
+	if (bytes == 0)
+		(void)printf("     0B");
+	else if (bytes > 10)
+		(void)printf(" %5.0f%c", bytes, "BKMGTPE"[unit]);
+	else
+		(void)printf(" %5.1f%c", bytes, "BKMGTPE"[unit]);
+}
+
+void
+prthuman(sfsp, used)
+	struct statfs *sfsp;
+	long used;
+{
+	prthumanval((double)(sfsp->f_blocks) * (double)(sfsp->f_bsize));
+	prthumanval((double)(used) * (double)(sfsp->f_bsize));
+	prthumanval((double)(sfsp->f_bavail) * (double)(sfsp->f_bsize));
 }
 
 /*
@@ -377,6 +452,6 @@
 usage()
 {
 	(void)fprintf(stderr,
-	    "usage: df [-ikn] [-t type] [file | filesystem ...]\n");
+	    "usage: df [-hikn] [-t type] [file | filesystem ...]\n");
 	exit(1);
 }
Only in df~: extern.h
Only in df~: vfslist.c

-- 
http://www.csis.gvsu.edu/matt
03 F8 23 C5 43 A2 F7 5A  24 49 F7 B0 3A F9 B1 7F
Try to understand everything, but believe nothing


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991129230436.A6501>