#!/bin/sh

umask 0077
SCRIPTNAME=$(basename $0 .sh)
DEFAULT_LOGFILE="/var/log/${SCRIPTNAME}.log"
LOGFILE="${DEFAULT_LOGFILE}"
LINES=10

OPTS=$(getopt -o sn:f:h --long swap,lines:,file:,help -- "$@")

if [ $? -ne 0 ]; then
  echo "Getopt returned with errorcode $?." >&2
  exit 1
fi

eval set -- "${OPTS}"

while true; do
  case "$1" in
    -s|--swap) sortbyswap=y; shift;;
    -n|--lines) [ -n "$2" ] && LINES="$2"; shift 2;;
    -f|--file) [ -n "$2" ] && LOGFILE="$2"; shift 2;;
    -h|--help) cat <<EOH
usage: $(basename $0) [-sh] [-n count] [-f logfile]
    -s, --swap
        List the top swap space using processes sorted by the SWAP column.
        By default the top RSS (see manpage of "ps" for RSS) using processes
        are listed sorted by the RSS column.
    -n, --lines=N
        List the top N processes.
    -f, --file=logfile
        Save the output to logfile (default: ${DEFAULT_LOGFILE})
    -h, --help
        Display this help and exit.
EOH
        exit 1;;
    --) shift; break;;
     *) echo "Error in getopt! Invalid parameter: $1" >&2; exit 1;;
  esac
done

echo >> "${LOGFILE}"
if [ $? -ne 0 -o ! -w "${LOGFILE}" ]; then
  echo "Could not write to logfile at ${LOGFILE}." >&2
  exit 1
fi

date >> "${LOGFILE}"

tmpfile=$(mktemp)
if [ ! -f "${tmpfile}" -o ! -w "${tmpfile}" ]; then
  echo "Error: failed to create temp file or file is not writable." >> "${LOGFILE}"
  exit 1
fi

ps -eo rss,vsz,user,pid,tty,time,cmd > "${tmpfile}"
set -- $(head -n1 "${tmpfile}")
if [ "${sortbyswap}" = "y" ]; then
  /bin/echo -n "SWAP $1" >> "${LOGFILE}"
else
  /bin/echo -n "$1 SWAP" >> "${LOGFILE}"
fi
shift; shift
/bin/echo " $*" >> "${LOGFILE}"
awkcmd='BEGIN {ORS=""; getline} {print '
if [ "${sortbyswap}" = "y" ]; then
  awkcmd="${awkcmd}"'$2 - $1 " " $1'
else
  awkcmd="${awkcmd}"'$1 " " $2 - $1'
fi
awkcmd="${awkcmd}"' " "; for (i=3; i<NF; i++) print $i " "; print $NF "\n"}'
awk "${awkcmd}" "${tmpfile}" | sort -rn | head -n ${LINES} >> "${LOGFILE}"
rm "${tmpfile}"


