1#! /bin/sh 2# $Id$ 3# vim:et:ft=sh:sts=2:sw=2 4# 5# Copyright 2008-2016 Kate Ward. All Rights Reserved. 6# Released under the Apache License. 7# 8# Author: kate.ward@forestent.com (Kate Ward) 9# 10# This library provides reusable functions that determine actual names and 11# versions of installed shells and the OS. The library can also be run as a 12# script if set execuatable. 13 14ARGV0=`basename "$0"` 15LSB_RELEASE='/etc/lsb-release' 16VERSIONS_SHELLS="/bin/bash /bin/dash /bin/ksh /bin/pdksh /bin/sh /bin/zsh" 17 18TRUE=0 19FALSE=1 20ERROR=2 21 22UNAME_R=`uname -r` 23UNAME_S=`uname -s` 24 25__versions_haveStrings=${ERROR} 26 27#------------------------------------------------------------------------------ 28# functions 29# 30 31versions_osName() 32{ 33 os_name_='unrecognized' 34 os_system_=${UNAME_S} 35 case ${os_system_} in 36 CYGWIN_NT-*) os_name_='Cygwin' ;; 37 Darwin) os_name_='Mac OS X' ;; 38 FreeBSD) os_name_='FreeBSD' ;; 39 Linux) os_name_='Linux' ;; 40 SunOS) 41 if grep 'OpenSolaris' /etc/release >/dev/null; then 42 os_name_='OpenSolaris' 43 else 44 os_name_='Solaris' 45 fi 46 ;; 47 esac 48 49 echo ${os_name_} 50 unset os_name_ os_system_ 51} 52 53versions_osVersion() 54{ 55 os_version_='unrecognized' 56 os_system_=${UNAME_S} 57 os_release_=${UNAME_R} 58 case ${os_system_} in 59 CYGWIN_NT-*) 60 os_version_=`expr "${os_release_}" : '\([0-9]*\.[0-9]\.[0-9]*\).*'` 61 ;; 62 Darwin) 63 major_='10' 64 sub_=`echo ${os_release_} |sed 's/^[0-9]*\.\([0-9]*\)\.[0-9]*$/\1/'` 65 case ${os_release_} in 66 8.*) minor_='4' ;; 67 9.*) minor_='5' ;; 68 10.*) minor_='6' ;; 69 11.*) minor_='7' ;; 70 12.*) minor_='8' ;; 71 13.*) minor_='9' ;; 72 15.*) minor_='10' ;; 73 *) minor_='X'; sub_='X' ;; 74 esac 75 os_version_="${major_}.${minor_}.${sub_}" 76 ;; 77 FreeBSD) 78 os_version_=`expr "${os_release_}" : '\([0-9]*\.[0-9]*\)-.*'` 79 ;; 80 Linux) 81 if [ -r "${LSB_RELEASE}" ]; then 82 if grep -q 'DISTRIB_ID=Ubuntu' "${LSB_RELEASE}"; then 83 os_version_=`cat "${LSB_RELEASE}" \ 84 |awk -F= '$1~/DISTRIB_DESCRIPTION/{print $2}' \ 85 |sed 's/"//g;s/ /-/g'` 86 fi 87 elif [ -r '/etc/redhat-release' ]; then 88 os_version_=`cat /etc/redhat-release` 89 fi 90 ;; 91 SunOS) 92 if grep 'OpenSolaris' /etc/release >/dev/null; then 93 os_version_=`grep 'OpenSolaris' /etc/release |awk '{print $2"("$3")"}'` 94 else 95 major_=`echo ${os_release_} |sed 's/[0-9]*\.\([0-9]*\)/\1/'` 96 minor_=`grep Solaris /etc/release |sed 's/[^u]*\(u[0-9]*\).*/\1/'` 97 os_version_="${major_}${minor_}" 98 fi 99 ;; 100 esac 101 102 echo ${os_version_} 103 unset os_name_ os_release_ os_version_ major_ minor_ sub_ 104} 105 106versions_shellVersion() 107{ 108 shell_=$1 109 110 if [ ! -x "${shell_}" ]; then 111 echo 'not installed' 112 return 113 fi 114 115 version_='' 116 case ${shell_} in 117 */sh) 118 # TODO(kward): fix this 119 ## this could be one of any number of shells. try until one fits. 120 #version_=`versions_shell_bash ${shell_}` 121 ## dash cannot be self determined yet 122 #[ -z "${version_}" ] && version_=`versions_shell_ksh ${shell_}` 123 ## pdksh is covered in versions_shell_ksh() 124 #[ -z "${version_}" ] && version_=`versions_shell_zsh ${shell_}` 125 ;; 126 */bash) version_=`versions_shell_bash ${shell_}` ;; 127 */dash) 128 # simply assuming Ubuntu Linux until somebody comes up with a better 129 # test. the following test will return an empty string if dash is not 130 # installed. 131 version_=`versions_shell_dash` 132 ;; 133 */ksh) version_=`versions_shell_ksh ${shell_}` ;; 134 */pdksh) version_=`versions_shell_pdksh ${shell_}` ;; 135 */zsh) version_=`versions_shell_zsh ${shell_}` ;; 136 *) version_='invalid' 137 esac 138 139 echo ${version_:-unknown} 140 unset shell_ version_ 141} 142 143versions_shell_bash() 144{ 145 $1 --version 2>&1 |grep 'GNU bash' |sed 's/.*version \([^ ]*\).*/\1/' 146} 147 148versions_shell_dash() 149{ 150 eval dpkg >/dev/null 2>&1 151 [ $? -eq 127 ] && return # return if dpkg not found 152 153 dpkg -l |grep ' dash ' |awk '{print $3}' 154} 155 156versions_shell_ksh() 157{ 158 versions_shell_=$1 159 160 # try a few different ways to figure out the version 161 versions_version_=`${versions_shell_} --version : 2>&1` 162 if [ $? -eq 0 ]; then 163 versions_version_=`echo "${versions_version_}" \ 164 |sed 's/.*\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\).*/\1/'` 165 else 166 versions_version_='' 167 fi 168 169 if [ -z "${versions_version_}" ]; then 170 _versions_have_strings 171 versions_version_=`strings ${versions_shell_} 2>&1 \ 172 |grep Version \ 173 |sed 's/^.*Version \(.*\)$/\1/;s/ s+ \$$//;s/ /-/g'` 174 fi 175 176 if [ -z "${versions_version_}" ]; then 177 versions_version_=`versions_shell_pdksh ${versions_shell_}` 178 fi 179 180 echo ${versions_version_} 181 unset versions_shell_ versions_version_ 182} 183 184versions_shell_pdksh() 185{ 186 _versions_have_strings 187 strings $1 2>&1 \ 188 |grep 'PD KSH' \ 189 |sed -e 's/.*PD KSH \(.*\)/\1/;s/ /-/g' 190} 191 192versions_shell_zsh() 193{ 194 versions_shell_=$1 195 196 # try a few different ways to figure out the version 197 versions_version_=`echo 'echo ${ZSH_VERSION}' |${versions_shell_}` 198 199 if [ -z "${versions_version_}" ]; then 200 versions_version_=`${versions_shell_} --version 2>&1 |awk '{print $2}'` 201 fi 202 203 echo ${versions_version_} 204 unset versions_shell_ versions_version_ 205} 206 207# Determine if the 'strings' binary installed. 208_versions_have_strings() 209{ 210 [ ${__versions_haveStrings} -ne ${ERROR} ] && return 211 eval strings /dev/null >/dev/null 2>&1 212 if [ $? -eq 0 ]; then 213 __versions_haveStrings=${TRUE} 214 else 215 echo 'WARN: strings not installed. try installing binutils?' >&2 216 __versions_haveStrings=${FALSE} 217 fi 218} 219 220#------------------------------------------------------------------------------ 221# main 222# 223 224versions_main() 225{ 226 # treat unset variables as an error 227 set -u 228 229 os_name=`versions_osName` 230 os_version=`versions_osVersion` 231 echo "os: ${os_name} version: ${os_version}" 232 233 for shell in ${VERSIONS_SHELLS}; do 234 shell_version=`versions_shellVersion ${shell}` 235 echo "shell: ${shell} version: ${shell_version}" 236 done 237} 238 239if [ "${ARGV0}" = 'versions' ]; then 240 versions_main "$@" 241fi 242