#!/bin/bash
#                       /usr/local/bin/df
#  http://crystalfaeries.net/posix/bin/df
# celeste:crystalfaery 2017-05-05 02:13:45+00:00
# This is a simple shell-script wrapper for the POSIX system command "df"
# which adds some GNU style "Long Options" to pretty-up df's output:
#
# Notice if you drop a "df" on the command line you get a completely
# randomly ordered display as a result... things are displayed in 
# internal data structure order, not human ordered patterns, so,
# one of the first things we think to do is sort the results in
# informative and useful manners, (and please weed out some of the
# less useful information from the display... as all those
# tmpfs "partitions" and "udev" virtual devices are not actually
# something I can manage the size of or fullness of...)
# 
# Usage: /usr/local/bin/df [--full]|[--available]|[--used]|[--mounts]|[--help]|[/bin/df <options>]
# --mounts	sorts partitions alphabetically by mount-point
# --available	sorts partitions by decreasing size of available space
# --used		sorts partitions by decreasing size of used      space
# --full		sorts partitions by decreasing percentage of fullness
# --help		displays /usr/local/bin/df help; <ENTER> to invoke '/bin/df --help':
# Usage: /bin/df [OPTION]... [FILE]...
# Show information about the file system on which each FILE resides,
# or all file systems by default.
# 
# Mandatory arguments to long options are mandatory for short options too.
#   -a, --all             include dummy file systems
#   -B, --block-size=SIZE  scale sizes by SIZE before printing them.  E.g.,
#                            `-BM' prints sizes in units of 1,048,576 bytes.
#                            See SIZE format below.
#       --total           produce a grand total
#   -h, --human-readable  print sizes in human readable format (e.g., 1K 234M 2G)
#   -H, --si              likewise, but use powers of 1000 not 1024
#   -i, --inodes          list inode information instead of block usage
#   -k                    like --block-size=1K
#   -l, --local           limit listing to local file systems
#       --no-sync         do not invoke sync before getting usage info (default)
#   -P, --portability     use the POSIX output format
#       --sync            invoke sync before getting usage info
#   -t, --type=TYPE       limit listing to file systems of type TYPE
#   -T, --print-type      print file system type
#   -x, --exclude-type=TYPE   limit listing to file systems not of type TYPE
#   -v                    (ignored)
#       --help     display this help and exit
#       --version  output version information and exit
# 
# Display values are in units of the first available SIZE from --block-size,
# and the DF_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables.
# Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set).
# 
# SIZE may be (or may be an integer optionally followed by) one of following:
# KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.
# 
# Report df bugs to bug-coreutils@gnu.org
# GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
# General help using GNU software: <http://www.gnu.org/gethelp/>
# For complete documentation, run: info coreutils 'df invocation'
# 
#  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
# 
# It seems the Darwin standard is to place /usr/local/bin at the tail of one's PATH
# On MacOSuX and discovered that by default the $PATH you get:
# $ echo $PATH
# (to see what your path is for command searches)
# places /usr/local/bin (home of this script) AFTER the system path /bin and
# /usr/bin so that it would not override (add functionality to) the system
# "df". :-( However, /opt/bin seems to be earlier in the path, so,
# installing this df script there would make it work :-)
# 
#  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
# 
# here is yet another approach to noticing which partitions are "too full":
#!/bin/bash
#function df_func { local dfts=$(ssh $1 "df -lP | tail -n +2 | sed 's/%//'"); echo $dfts | awk '$5 > 90 {exit 1}' > /dev/null; if [ $? == 1 ]; then echo -n "$1 "; echo $dfts | awk '$5 > 90 {printf "%s %d%%\n", $6, $5}'; fi }
#df_func $1

# CONFIGURATION:
# reorder next two lines, (last is effective), to use (or not) -h option in displaying our results
h="-h"		# -h option won't sort correctly?
h=""		# -h option won't sort correctly?
df=/bin/df	# the real df, which presumably we have taken-over-for by being earlier in search path

# COMMAND-LINE ARGUMENTS:
while [[ $# -ne 0 ]]
do
	case "$1" in
	"--help") 
		echo "Usage: $0 [--full]|[--available]|[--used]|[--mounts]|[--help]|[$df <options>]"
		echo "--full	  sorts partitions by decreasing percentage of fullness"
		echo "--available sorts partitions by decreasing size of available space"
		echo "--used	  sorts partitions by decreasing size of used      space"
		echo "--mounts	  sorts partitions alphabetically by mount-point"
		echo -n "--help	  displays $0 help; <ENTER> to invoke '$df --help':"
		read answer
		exec $df "$@" | less
		exit $?
	;;
	--used)
#echo "Filesystem	1024-blocks	Used	Available	Capacity	Mounted_on"
# NOTE: should rewrite to use a temp file instead of calling /bin/df twice.
		$df $h -P | sed 's/Mounted on/Mounted_on/' | column -t | head -n  1 
		$df $h -P | sed 's/Mounted on/Mounted_on/' | column -t | tail -n +2 | sort -rn -k3,3 | grep -v tmpfs | grep -v udev
		exit $?
	;;
	--available)
#echo "Filesystem	1024-blocks	Used	Available	Capacity	Mounted_on"
# NOTE: should rewrite to use a temp file instead of calling /bin/df twice.
		$df $h -P | sed 's/Mounted on/Mounted_on/' | column -t | head -n  1 
		$df $h -P | sed 's/Mounted on/Mounted_on/' | column -t | tail -n +2 | sort -rn -k4,4 | grep -v tmpfs | grep -v udev
		exit $?
	;;
	--full)
#echo "Filesystem	1024-blocks	Used	Available	Capacity	Mounted_on"
# NOTE: should rewrite to use a temp file instead of calling /bin/df twice.
		$df $h -P | sed 's/Mounted on/Mounted_on/' | column -t | head -n  1 
		$df $h -P | sed 's/Mounted on/Mounted_on/' | column -t | tail -n +2 | sort -rn -k5,5 | grep -v tmpfs | grep -v udev
		exit $?
	;;
	--mounts)
#echo "Filesystem	1024-blocks	Used	Available	Capacity	Mounted_on"
# NOTE: should rewrite to use a temp file instead of calling /bin/df twice.
		$df $h -P | sed 's/Mounted on/Mounted_on/' | column -t | head -n  1 
		$df $h -P | sed 's/Mounted on/Mounted_on/' | column -t | tail -n +2 | sort -k6,6 | grep -v tmpfs | grep -v udev 
		exit $?
	;;
	*)
		exec $df "$@"	# pass all arguments through
		exit $?
	;;
	esac
	shift
done
exec $df "$@"	# pass all arguments through
let result=$?
if [[ $result -ne 0 ]]
then
	echo "$0 exit: $result" 1>&2	# error message on stderr
fi
exit $result


syntax highlighted by Code2HTML, v. 0.9.1