#!/bin/bash # # Author: Georg Voell - georg.voell@standby.cloud # Version: @(#)get-platform 3.2.1 25.09.2024 (c)2024 Standby.cloud # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ # # This script can be used free of charge. Use it as is or customize as needed. It is not guaranteed to be # error free and you will not be reimbursed for any damage it may cause. # #@ Get some infos about the platform (OS) and machine. #@ #@Usage: get-platform [options] [keys] #@ Options: #@ -h, --help : Displays helptext. #@ -v, --version : Displays the version of the script. #@ -o, --output : Output format: can be "plain" (default), "keys", "json", "tsv", "line" or "table". #@ Keys: Optional - Select the keys you want to display. Use a colon (default) or tab or comma separated string for keys e.g. #@ os: Displays the Operation System e.g. "Linux", "Darwin", "SunOS". #@ id: Displays the id e.g. "ol", "FreeBSD" #@ #@Examples: #@ pname=`get-platform pretty_name` #@ echo "$pname" # will display e.g. "Oracle Linux Server 7.4" # # Exit codes: # 01: Unknown or wrong parameter. # 02: Unsupported OS. # 03: Unknown key. # # See also: # **get-ip**(1), **check-port**(1), **install-scripts**(1) # # More examples: # # get-platform --output keys # # os:Linux # os_id:GNU/Linux # id:ol # id_like:fedora # platform:x86_64 # name:Oracle Linux Server # codename: # cpe_name:cpe:/o:oracle:linux:9:4:server # version_id:9.4 # version_main:9 # pretty_name:Oracle Linux Server 9.4 # machine:x86_64 # processor:i386 # bit:64 # release:5.15.0-209.161.7.1.el9uek.x86_64 # date:#2 SMP Mon Aug 12 18:53:13 PDT 2024 # gateway:192.168.0.129 # interface:enp0s5 # up:true # ip_v4:192.168.0.131 # ip_v6:fe80::17ff:fe0d:12bf # fqdn:operator.oper.vcnfra.oraclevcn.com # nodename:operator # # Example output for MacOS Catalina: # # get-platform --output json # # { # "content": { # "os": "Darwin", # "os_id": "OSX", # "id": "FreeBSD", # "id_like": "posix", # "platform": "Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz", # "name": "macOS", # "codename": "Catalina", # "version_id": "10.15.7", # "version_main": 19, # "pretty_name": "macOS 10.15.7 (Catalina)", # "machine": "x86_64", # "processor": "i386", # "bit": 64, # "release": "19.6.0", # "date": "Darwin Kernel Version 19.6.0: Tue Jun 21 21:18:39 PDT 2022; root:xnu-6153.141.66~1/RELEASE_X86_64", # "gateway": "fritz.box", # "interface": "en0", # "up": true, # "ip_v4": "192.168.178.51" # "ip_v6": "2003:cf:474e:bf00:a071:89a1:da66:e1ec", # "fqdn": "Georgs-MacBook-Pro-2.fritz.box", # "nodename": "Georgs-MBP-2.fritz.box" # }, # "contentItems": 1, # "creator": "get-platform" # } # # Update history: # # V 3.0.0 24.04.2020 New version # V 3.0.1 11.06.2020 Using library # V 3.1.0 05.06.2023 New copyright # V 3.1.1 09.08.2024 Using print-table # V 3.2.0 11.08.2024 New minor version: New JSON output with 'content' # V 3.2.1 25.09.2024 Autonomous wasn't recognized # # Find executable bash library and source it lib=`which lib.bash 2>/dev/null | sed 's|^no 'lib.bash' in .*||'` if [ "$lib" != "" ]; then source "$lib" else progdir=`dirname "$0"` if [ -r "${progdir}/lib.bash" ]; then source "${progdir}/lib.bash" else echo "Unexpected error: Unable to locate bash library 'lib.bash'." exit 1 fi fi # Do extra cleanup function ExtraCleanup() { filecheck -rm ${scratchfile}.out } # Preset param="" formatstr="" # Check parameters: Loop until all parameters are used up while [ $# -gt 0 ]; do pname=${1} case "$pname" in -o | --output) shift if [ "$1" != "" ]; then if [ "$formatstr" = "" ]; then formatstr=`echo "$1" | tolower` if [ "$formatstr" != "plain" -a "$formatstr" != "keys" -a "$formatstr" != "json" -a "$formatstr" != "tsv" -a "$formatstr" != "line" \ -a "$formatstr" != "table" ]; then errstr="Unknown format '$formatstr' after parameter '$pname'. Please choose from 'plain', 'keys', 'json', 'tsv', 'line' or 'table'." fi else errstr="Option '$pname' used more then once." fi shift else errstr="Please specify a format ('plain', 'keys', 'json', 'tsv', 'line' or 'table') after parameter '$pname'." fi ;; -v | --version) shift showversion=true ;; -h | --help) shift showhelp=true ;; *) shift paramck=`echo "$pname" | grep '^-'` # Keys don't begin with '-' if [ "$paramck" != "" ]; then errstr="Unknown option '$pname'." else if [ "$param" = "" ]; then param="$pname" else errstr="Keys were already specified '$param'. Unknown additional parameter: '$pname'." fi fi esac done # Check if we can reformat the output pt=`filecheck -x print-table` #if [ "$pt" = "" ]; then # errstr="Script 'print-table' not found." #fi # Display help or error message DisplayHelp # Set output to plain if not specified if [ "$formatstr" = "" ]; then formatstr="plain" fi # https://en.wikipedia.org/wiki/Uname uname=`filecheck -x uname` if [ "$uname" != "" ]; then os=`$uname -s 2>/dev/null` # (system) e.g. Darwin, SunOS, Linux, Windows_NT, CYGWIN_NT-5.1, MS-DOS, GNU, FreeBSD, HP-UX, AIX, OS400, OpenBSD, ULTRIX, OS/390 rel=`$uname -r 2>/dev/null` # (kernel release) e.g. 5.11 for Solaris 11 or 4.14.35-1902.5.2.2.el7uek.x86_64 (Oracle Linux) mach=`$uname -m 2>/dev/null` # (machine) e.g. i86pc (Solaris) or x86_64 (Linux + Mac), armv7l, sparc64, ppc, ppc64, i686, x86, i386, amd64, sun4u, i86pc, alpha vers=`$uname -v 2>/dev/null` # (kernel version) e.g. 11.3 for Solaris 11.3 or #2 SMP Fri Sep 20 00:39:39 GMT 2019 (Oracle Linux) proc=`$uname -p 2>/dev/null` # (processor) e.g. i386 (Mac and Solaris) or x86_64 (Linux), sparc64, ppc64, i686, amd64, x86_64, sun4u, powerpc, sparc, alpha, x64 node=`$uname -n 2>/dev/null` # (nodename) e.g. $HOSTNAME osid=`$uname -o 2>/dev/null` # (operating system) e.g. Linux, MS/Windows, Cygwin, GNU, GNU/Linux, FreeBSD, Msys, Solaris plat=`$uname -i 2>/dev/null` # (hardware platform) e.g. UltraSPARC T1, i386, AMD Sempron(tm) Processor 3000+, GENERIC, i386, x86_64, i386, i86pc, SUNW,Sun-Fire-280R else os="" rel="" mach="" vers="" proc="" node="" osid="" plat="" fi # Dertermine local hostname and ip hostname=`filecheck -x hostname` if [ "$hostname" != "" ]; then if [ "$node" = "" ]; then node=`"$hostname" 2>/dev/null` fi if [ "$lip" = "" ]; then lip=`"$hostname" -I 2>/dev/null | awk '{print $1}'` fi fi # Network gateway="" iface="" lip="" lipv6="" lipdns="" # Check for ifconfig ifconfig=`filecheck -x ifconfig` if [ "$ifconfig" != "" ]; then if [ "$os" = "Darwin" ]; then iproute=`filecheck -x route` result=`"$iproute" get 8.8.8.8 2>/dev/null` if [ "$result" != "" ]; then gateway=`echo "$result" | grep 'gateway:' | cut -d':' -f2 | sed 's|^ ||'` iface=`echo "$result" | grep 'interface:' | cut -d':' -f2 | sed 's|^ ||'` fi else iproute=`filecheck -x ip` result=`"$iproute" route show 2>/dev/null | grep '^default ' | head -n 1` if [ "$result" != "" ]; then gateway=`echo "$result" | cut -d' ' -f3` iface=`echo "$result" | cut -d' ' -f5` fi fi "$ifconfig" "$iface" > $scratchfile 2>/dev/null lip=`grep "inet " $scratchfile | head -n 1 | awk '{print $2}'` lipv6=`grep "inet6 " $scratchfile | head -n 1 | awk '{print $2}'` up=`grep '^'"${iface}"': .* $scratchfile 2>/dev/null lipdns=`cat $scratchfile | grep "name = ${node}\." | cut -d'=' -f2 | sed 's|^ ||' | sed 's|\.$||'` if [ "$lipdns" = "" ]; then lipdns=`cat $scratchfile | grep "name = " | head -n 1 | cut -d'=' -f2 | sed 's|^ ||' | sed 's|\.$||'` fi fi if [ "$os" = "SunOS" ]; then isainfo=`filecheck -x isainfo` if [ "$isainfo" != "" ]; then bits=`isainfo -b` else getconf=`filecheck -x getconf` if [ "$getconf" != "" ]; then bits=`$getconf LONG_BIT 2>/dev/null` else bits="" fi fi else grepres=`echo $proc | grep "^x86"` if [ "$grepres" != "" ]; then proc="i386" fi getconf=`filecheck -x getconf` if [ "$getconf" != "" ]; then bits=`$getconf LONG_BIT 2>/dev/null` else bits="" fi fi # Try to get OS Name case "$os" in Linux) # Check if there are infos in release files if [ -f /etc/os-release ]; then name=`grep "^NAME=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` version=`grep "^VERSION_ID=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` mainvers=`echo $version | cut -d'.' -f1` osstr=`grep "^PRETTY_NAME=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` id=`grep "^ID=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` idlike=`grep "^ID_LIKE=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` cpename=`grep "^CPE_NAME=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` else # We should have a /etc/os-release file. Otherwise there may is also redhat-release, SuSE-release, lsb-release (Debian) if [ -f /etc/system-release ]; then name=`head -n 1 /etc/system-release | awk -F ' release ' '{print $NR}'` version=`head -n 1 /etc/system-release | awk -F ' release ' '{print $NF}' | cut -d' ' -f1` mainvers=`echo $version | cut -d'.' -f1` else name="$os" version="$rel" fi fi # Try do determine codename if [ "$id" = "ol" -o "$id" = "centos" ]; then idlike="fedora" if [ -f /etc/system-release ]; then grepres=`head -n 1 /etc/system-release | grep "("` if [ "$grepres" != "" ]; then codename=`head -n 1 /etc/system-release | cut -d'(' -f2 | cut -d')' -f1` fi else codename="" fi else if [ "$id" = "ubuntu" -o "$id" = "debian" ]; then idlike="debian" if [ -f /etc/os-release ]; then grepres=`grep "^VERSION=" /etc/os-release | grep "("` if [ "$grepres" != "" ]; then codename=`grep "^VERSION=" /etc/os-release | cut -d'"' -f2 | cut -d'(' -f2 | cut -d')' -f1` fi fi else if [ "$id" = "rhel" ]; then idlike="fedora" if [ -f /etc/redhat-release ]; then grepres=`head -n 1 /etc/redhat-release | grep "("` if [ "$grepres" != "" ]; then codename=`head -n 1 /etc/redhat-release | cut -d'"' -f2 | cut -d'(' -f2 | cut -d')' -f1` fi fi else if [ "$id" = "opensuse" -o "$id" = "sles" ]; then idlike="suse" if [ -f /etc/SuSE-release ]; then grepres=`head -n 1 /etc/SuSE-release | grep "("` if [ "$grepres" != "" ]; then codename=`head -n 1 /etc/SuSE-release | cut -d'"' -f2 | cut -d'(' -f2 | cut -d')' -f1` fi fi else codename="" fi fi fi fi # Convert aarch64 to arm if [ "$proc" = "aarch64" ]; then proc="arm" fi # Check if we are on autonomous linux if codename i snot defined if [ "$codename" = "" -a "$id" = "ol" ]; then rpm=`filecheck -x rpm` if [ "$rpm" != "" ]; then $rpm -q alx-utils > /dev/null 2>&1 # al-config stat=$? if [ $stat -eq 0 ]; then codename="Oracle Autonomous Linux" else codename="Oracle Enterprise Linux" fi fi fi if [ "$codename" != "" ]; then if [ "$id" = "ubuntu" -o "$id" = "sles" ]; then osname="$osstr (${codename})" else osname="$name $version (${codename})" fi else osname="$name $version" fi ;; SunOS) # /usr/lib/os-release if [ -f /etc/os-release ]; then name=`grep "^NAME=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` version=`grep "^VERSION_ID=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` osstr=`grep "^PRETTY_NAME=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` id=`grep "^ID=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` idlike=`grep "^ID_LIKE=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` cpename=`grep "^CPE_NAME=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2` fi if [ -f /etc/release ]; then osstr=`head -1 /etc/release | sed 's|^ *||'` datestr=`tail -1 /etc/release | sed 's|^ *||'` vers="$vers $datestr" fi if [ "$version" = "" ]; then name="Sun Solaris" mainvers=`echo $rel | sed 's|^5.||'` if [ "$osstr" = "" ]; then version="$mainvers" else substr=`echo "$osstr" | cut -d'_' -f2 | sed 's|^u||' | sed 's|wos$||'` if [ "$substr" = "" ]; then version="$mainvers" else version=`echo ${mainvers}.$substr` fi fi else mainvers=`echo $version | cut -d'.' -f1` fi if [ "$osid" = "" ]; then name="Solaris" fi if [ "$name" = "" ]; then name="Sun Solaris" fi if [ "$id" = "" ]; then id="solaris" fi if [ "$idlike" = "" ]; then idlike="posix" fi if [ "$osstr" != "" ]; then osname="$osstr" else osname="$name $vers $proc" fi ;; Darwin) # system_profiler SPSoftwareDataType or system_profiler to get more information if [ "$osid" = "" ]; then osid="OSX" fi if [ "$plat" = "" ]; then plat=`sysctl -n machdep.cpu.brand_string` fi sw_vers=`filecheck -x sw_vers` if [ "$sw_vers" != "" ]; then name=`$sw_vers -productName` id="FreeBSD" idlike="posix" version=`$sw_vers -productVersion` # mainvers=`echo $version | cut -d'.' -f2` mainvers=`echo $rel | cut -d'.' -f1` # "Cheetah" "Puma" StringArray=("Titan" "Hera" "Unknown" "Kodiak" "Cheetah" "Puma" "Jaguar" "Panther" "Tiger" "Leopard" "Snow Leopard" "Lion" "Mountain Lion" \ "Mavericks" "Yosemite" "El Capitan" "Sierra" "High Sierra" "Mojave" "Catalina" "Big Sur" "Monterey" "Ventura" "Sonoma" "Sequoia") if [ $mainvers -lt 0 -o $mainvers -gt 24 ]; then # Get codename from current license file codename=`awk '/SOFTWARE LICENSE AGREEMENT FOR macOS/' \ '/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf' \ | awk -F 'macOS ' '{print $NF}'` else codename="${StringArray[$mainvers]}" if [ $mainvers -gt 15 ]; then name="macOS" else if [ $mainvers -gt 11 ]; then name="OS X" fi fi fi if [ "$codename" != "" ]; then osname="$name $version ($codename)" else osname="$name $version" fi else # ToDo: More Parameter name="Mac OS X" osname="$vers" fi ;; *) exitcode=2 errormsg $exitcode "($progstr) Unsupported OS '$os'" exit $exitcode ;; esac # Don't display codename or cpename in JSON if it's empty if [ "$codename" = "" ]; then codename="//" fi if [ "$cpename" = "" ]; then cpename="//" fi if [ "$gateway" = "" ]; then gateway="//" fi if [ "$iface" = "" ]; then iface="//" fi if [ "$lip" = "" ]; then lip="//" fi if [ "$lipv6" = "" ]; then lipv6="//" fi if [ "$lipdns" = "" ]; then lipdns="//" fi # Create header with all our parameter names and write it as tsv printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" "os" "os_id" "id" "id_like" "platform" "name" \ "codename" "cpe_name" "version_id" "version_main" "pretty_name" "machine" "processor" "bit" "release" "date" \ "gateway" "interface" "up" "ip_v4" "ip_v6" "fqdn" "nodename" > $scratchfile # Create body with all infos and append it to tsv printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" "$os" "$osid" "$id" "$idlike" "$plat" "$name" \ "$codename" "$cpename" "$version" "/${mainvers}/" "$osname" "$mach" "$proc" "/${bits}/" "$rel" "$vers" \ "$gateway" "$iface" "/$up/" "$lip" "$lipv6" "$lipdns" "$node" >> $scratchfile # Display everything if [ "$pt" = "" ]; then # No print-table found - just display the tsv file cat $scratchfile else cat $scratchfile | $pt "$param" --output "$formatstr" --quiet > ${scratchfile}.out stat=$? if [ $stat -eq 3 ]; then exitcode=3 errormsg $exitcode "($progstr) None of the specified keys '$param' were found." else if [ "$ENVELOPE_TABLE" = false -o "$formatstr" != "json" ]; then cat ${scratchfile}.out else cat ${scratchfile}.out | sed 's|\("contentItems":.*\)|\1,\n "creator": "'$progstr'"|' fi fi fi # Cleanup and exit Cleanup exit $exitcode