#!/bin/bash
#< Grab specific information from RPM headers, and display in order specified
# Only caveat here is you can't use this script the way getopts is itended, i.e.
# mycmd -pvPsr
# Reason? Because I wanted to allow ordering of options, thus
# mycmd -p -P -v
# and
# mycmd -P -v -p
# are two different output formats
# Executable paths
BASENAME="/bin/basename"
CUT="/usr/bin/cut"
ECHO="/bin/echo"
EGREP="/bin/egrep"
GREP="/bin/grep"
RM="/bin/rm"
RPM="/bin/rpm"
SED="/bin/sed"
SORT="/bin/sort"
UNAME="/bin/uname"
WC="/usr/bin/wc"
# RPM with options
RPM_ALL="${RPM} -qa"
RPM_DETAIL="${RPM} -qi"
# File paths
REDHAT_RELEASE="/etc/redhat-release"
# Option modes
CSV_MODE=0
FULL_PKG_NAME=0
PKG_NAME=0
REL_NUM=0
SUMMARY=0
VER_NUM=0
# Other vars
DELIM=" "
THIS_PROG=$( ${BASENAME} $0 )
TMPFILE="/tmp/${THIS_PROG}.$$"
# Exit codes
SUCCESS=0
ERROR=1
function cleanup {
${RM} -f ${TMPFILE}
}
trap "cleanup; exit ${ERROR}" 1 2 3 15
function print_error {
${ECHO} "Error: $@" >&2
}
function print_usage {
{
${ECHO} "Usage: ${THIS_PROG} [-c] [-p][-P][-r][-s][-v]"
${ECHO} " -c Print output in csv format"
${ECHO} " -p Show short package name"
${ECHO} " -P Show full package/rpm name"
${ECHO} " -r Show release"
${ECHO} " -s Show package summary"
${ECHO} " -v Show version"
} >&2
}
function check_os {
OS=$( ${UNAME} )
case ${OS} in
"Linux") if [ ! -f "${REDHAT_RELEASE}" ]; then
print_error "Only Redhat Linux is supported by this script"
exit ${ERROR}
fi
;;
* ) print_error "Only Redhat Linux is supported by this script"
exit ${ERROR}
;;
esac
}
function get_rpm_info {
if [ "${CSV_MODE}" -eq "1" ]; then
DELIM=","
fi
${RPM_ALL} | ${SORT} -k 1,1 | while read PACKAGE; do
if [ "${FULL_PKG_NAME}" -eq "1" ]; then
${ECHO} "PACKAGE=${PACKAGE}" >> ${TMPFILE}
fi
${RPM_DETAIL} ${PACKAGE} | while read DETAIL; do
if [ "${PKG_NAME}" -eq "1" ]; then
${ECHO} "${DETAIL}" | ${EGREP} '^Name[[:space:]]+:' >/dev/null 2>&1
if [ "$?" -eq "0" ]; then
pNAME=$( ${ECHO} "${DETAIL}" | ${EGREP} '^Name[[:space:]]+:' |\
${SED} 's/^Name[ ][ ]*:[ ]\([^ ]*\)[ ][ ]*.*$/\1/' )
${ECHO} "pNAME=${pNAME}" >> ${TMPFILE}
fi
fi
if [ "${VER_NUM}" -eq "1" ]; then
${ECHO} "${DETAIL}" | ${EGREP} '^Version[[:space:]]+:' >/dev/null 2>&1
if [ "$?" -eq "0" ]; then
pVERSION=$( ${ECHO} "${DETAIL}" | ${EGREP} '^Version[[:space:]]+:' |\
${SED} 's/^Version[ ][ ]*:[ ]\([^ ]*\)[ ][ ]*.*$/\1/' )
${ECHO} "pVERSION=${pVERSION}" >> ${TMPFILE}
fi
fi
if [ "${REL_NUM}" -eq "1" ]; then
${ECHO} "${DETAIL}" | ${EGREP} '^Release[[:space:]]+:' >/dev/null 2>&1
if [ "$?" -eq "0" ]; then
pRELEASE=$( ${ECHO} "${DETAIL}" | ${EGREP} '^Release[[:space:]]+:' |\
${SED} 's/^Release[ ][ ]*:[ ]\([^ ]*\)[ ][ ]*.*$/\1/' )
${ECHO} "pRELEASE=${pRELEASE}" >> ${TMPFILE}
fi
fi
if [ "${SUMMARY}" -eq "1" ]; then
${ECHO} "${DETAIL}" | ${EGREP} '^Summary[[:space:]]+:' >/dev/null 2>&1
if [ "$?" -eq "0" ]; then
pSUMMARY=$( ${ECHO} "${DETAIL}" | ${EGREP} '^Summary[[:space:]]+:' |\
${SED} -e 's/^Summary[ ][ ]*:[ ]\(.*\)/\1/' -e 's/,//g' )
${ECHO} "pSUMMARY=${pSUMMARY}" >> ${TMPFILE}
fi
fi
done
# The reason we do this is so that ordering of output fields is honoured
OPT_LIST=$( ${ECHO} "${FULL_CMD_LIST}" |\
${SED} -e 's/-c//g' -e 's/-p/pNAME/g' -e 's/-P/PACKAGE/g' \
-e 's/-r/pRELEASE/g' -e 's/-s/pSUMMARY/g' -e 's/-v/pVERSION/g' )
NUM_PARAMS=$( ${ECHO} "${OPT_LIST}" | ${WC} -w )
COUNTER=0
for PARAM in ${OPT_LIST}; do
let "COUNTER = $COUNTER + 1"
CURRENT=$( ${GREP} "^${PARAM}=" ${TMPFILE} | ${CUT} -d= -f2 )
if [ "${COUNTER}" -lt "${NUM_PARAMS}" ]; then
${ECHO} -e "${CURRENT}${DELIM}\c"
else
${ECHO} -e "${CURRENT}\c"
fi
done
> ${TMPFILE}
${ECHO}
done
}
#
# main()
#
FULL_CMD_LIST="$@"
while getopts ":cpPrsv" OPTION; do
case ${OPTION} in
"c" ) CSV_MODE=1
;;
"p" ) PKG_NAME=1
;;
"P" ) FULL_PKG_NAME=1
;;
"r" ) REL_NUM=1
;;
"s" ) SUMMARY=1
;;
"v" ) VER_NUM=1
;;
* ) print_usage
exit ${ERROR}
;;
esac
done
shift $(( ${OPTIND} - 1 ))
if [ "${PKG_NAME}" -eq "0" -a "${FULL_PKG_NAME}" -eq "0" -a "${REL_NUM}" -eq "0" -a "${SUMMARY}" -eq "0" -a "${VER_NUM}" -eq "0" ]; then
print_error "At least one information option must be specified"
exit "${ERROR}"
fi
check_os
get_rpm_info
cleanup
exit ${SUCCESS}