Shell Scriptlets

This post will be continually developed. I recently designed some solutions to solve some issues with init.d and setup scripts. These may be of use to others, and I will likely reuse them.

Real path using Python

The following scriptlet finds the real path for the script and its scriptname. This is in old sh format.

SCRIPT=`python -c "import os,sys; print os.path.realpath(sys.argv[1])" ${0}`
SCRIPTNAME=`dirname ${SCRIPT}`

Boot Wrap

Most init.d scripts start the application as root. This can be a security issue as if the launched program is compromised, then the whole system can be compromised. This wrapper reruns the script as the appropriate user when run as root. It also allows members of a group to run the script via sudo. Due to some init systems requiring old sh syntax it is written accordingly. Replace the WRAPPED_USER and RUNFROM_GROUP values as required.

# Run the script using appropriate user - Replaces separate boot_wrap script
WRAPPED_USER=daemon
RUNFROM_GROUP=admin
OS=`uname -s`
[ "$OS" = SunOS ] && PATH=/usr/xpg4/bin:$PATH  # Use modern id command on Solaris
if [ "$(id -un)" != ${WRAPPED_USER} ]; then
    if [ "$(id -u)" = 0 ]; then
        lockfile=/var/lock/subsys/${SCRIPTNAME}
        if [ "${1}" = start ]; then
            [ "$OS" = Linux ] && touch ${lockfile}
        elif [ "${1}" = stop ]; then
            [ "$OS" = Linux ] && rm -f ${lockfile}
        fi
        su ${WRAPPED_USER} -c "${0} ${1}"
    elif expr "$(groups)" : ".*${RUNFROM_GROUP}" 1>/dev/null; then
        sudo -u ${WRAPPED_USER} ${0} ${1}
    else
        echo "${LOGNAME} is not permitted to run this script"
    fi
    exit $?
fi

# Now running as the correct user - verify
if [ "`id -un`" != ${WRAPPED_USER} ]; then
    echo FATAL: not running as ${WRAPPED_USER}
    exit -1
fi

Conditional Install/Update File

The following function conditionally updates a file if it is missing or updated. This is coded for newer environments where diff -q is available. It does not verify that the source can be read or the destination written.

# Function to update or install file only if missing or changed
updateChanged() {
    if [ ! -f ${1} ]; then
        echo FATAL: Source file ${1} is missing
        exit 1
    elif [ ! -f ${2} ]; then
        echo Installing: ${2}
        cp ${1} ${2}
        return 0
    elif ! diff -q ${1} ${2} >/dev/null; then
        echo Updating: ${2}
        cp ${2}{,.$(date +%Y%m%dT%H%M)}
        cp ${1} ${2}
        return 0
    fi
    return 1
}