Installing and removing kernel module RPMs
Should this be a shell script?

You mentioned that you wrote this script to push the packages to over 60 servers.  If you have that many servers, then you should have a configuration management tool to do these kinds of tasks for you and much, much more.  Typical solutions include Ansible, CFengine, Chef, and Puppet.

Instead of copying the RPMs to each machine, you should probably use a YUM repository, which may be one that you operate yourself, if those are self-built RPMs.

Version check

modinfo enic |grep "^version" |awk '{print $2}' would be better written as modinfo -F version enic 2&gt;/dev/null.  I recommend discarding error messages there, in case no such module is available.

However, I wonder why you bother querying modinfo at all, instead of just running yum and letting it automatically decide whether anything needs to be installed at all.

The conditionals are slightly redundant.  You could just write

if [ $enic_ood -a $fnic_ood ]; then
    …
elif [ $enic_ood ]; then
    …
elif [ $fnic_ood ]; then
    …
else
    …
fi


I get the feeling, though, that nearly everything in the script is written twice.  You could write a loop that handles both packages:

need_rpms=
for module in enic fnic ; do
    rpm=$HOME/kmod-$module-*.rpm
    want_version=$(rpm -qp --queryformat '%{VERSION}' $rpm)
    installed_version=$(/sbin/modinfo -F version "$module" 2&gt;/dev/null)
    if [ "$want_version" = "$installed_version" ]; then
        echo "$module is already up-to-date: $installed_version"
    else
        need_rpms="$need_rpms $rpm"
    fi
done

if [ -n "$need_rpms" ]; then
    /usr/bin/yum -y localinstall $need_rpms
done


Alternatively, you could have one script that takes parameters, and run it once for each package.

Program structure

There should be an install() function and a remove() function.

Don't set yum='/usr/bin/yum -y localinstall' in one place and yum='/usr/bin/yum -y remove' in another place.  I would expect it to be uniformly defined as yum='/usr/bin/yum -y', just like modinfo='/sbin/modinfo'.

This script always appears to succeed.  Fatal errors should cause the script to exit with a non-zero status, and error messages should be printed to standard error.  Exit statuses matter; even when executing the script over SSH, for example, the error status propagates all the way back to become the exit status of SSH.

install() {
    …
}

remove() {
    …
}

case "$1" in
  install|remove)
    "$1"
    ;;
  *)
    echo "$0 must be executed with either 'install' or 'remove'" &gt;&amp;2
    exit 1
    ;;
esac