#!/usr/bin/env bash # # Author: Georg Voell - georg.voell@standby.cloud # Version: @(#)check-version 3.3.1 16.03.2026 (c)2026 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 the version of a script and tries to get the version for some tools. #@ Result is toolname with path, version, compare string. #@ If tool is not installed, it returns "tool not found". #@ #@Usage: check-version [options] tool #@ Options: #@ -h, --help : Displays helptext. #@ -v, --version : Displays the version of the script. #@ -m, --min : Minimum version that the tool has to have at least. #@ -x, --max : Maximum version that the tool can have. #@ Tool: List of tools is limited e.g.: #@ jq : Displays the version of installed jq. #@ java : Displays the version of installed java. #@ python: Displays the version of installed python. #@ #@Examples: #@ check-version java #@ Displays version of installed java e.g. "/usr/bin/java 1.8.0.212 found". #@ check-version jq --min 1.5 #@ Displays version of installed jq and if it is >= 1.5 e.g. "/usr/local/bin/jq 1.6 ok". # # Exit codes: # 01: Unknown or wrong parameter. # # Update history: # # V 3.0.0 24.04.2020 New version # V 3.0.1 11.06.2020 Using library # V 3.0.2 02.07.2020 Tab separated output # V 3.0.3 23.09.2020 Packer included # V 3.0.4 24.10.2020 Check for gnu sed # V 3.0.5 31.01.2021 Check for ansible # V 3.0.6 03.09.2022 Output with blanks instead of tabs # V 3.1.0 05.06.2023 New copyright # V 3.1.1 24.08.2023 Fix getting version from older nslookup # V 3.1.2 07.09.2023 Fix for gsed and gtail # V 3.2.0 07.09.2024 New minor version # V 3.3.0 19.01.2026 Revised with support of Claude Code # V 3.3.1 16.03.2026 Optimized: replaced backticks with $(); [ ] with [[ ]]; # echo|grep with [[ == -* ]] or [[ =~ ]]; replaced [ -a ] with && # # Find executable bash library and source it lib=$(command -v lib.bash 2>/dev/null) if [[ -n "$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 # Preset param="" minimum="" maximum="" # Check parameters: Loop until all parameters are used up while [[ $# -gt 0 ]]; do pname="${1}" case "$1" in -m | --min) shift if [[ -n "$1" ]]; then minimum="$1" shift else errstr="Please specify a minimum version (e.g. 1.5) after parameter '$pname'." fi ;; -x | --max) shift if [[ -n "$1" ]]; then maximum="$1" shift else errstr="Please specify a maximum version (e.g. 2.1) after parameter '$pname'." fi ;; -v | --version) shift showversion=true ;; -h | --help) shift showhelp=true ;; *) shift if [[ "$pname" == -* ]]; then errstr="Unknown option '$pname'." else if [[ -z "$param" ]]; then param="$pname" else errstr="Unknown parameter: '$pname'." fi fi ;; esac done # Plausibility check if [[ -z "$param" ]]; then errstr="Call '$progstr' with a filename e.g. a script or a tool." fi # Display help or error message DisplayHelp # Set some defaults okstr="found" tool=$(filecheck -x "$param") if [[ -z "$tool" ]]; then printf '%s not found\n' "$param" exit 2 else description="need reinstallation" cmd=$(basename "$param") case "$cmd" in file) version=$($tool --version 2>/dev/null | head -n 1 | cut -d'-' -f2) stat=$? if [[ $stat -ne 0 || -z "$version" ]]; then version="1.0" fi ;; grep) version=$($tool --version 2>/dev/null) stat=$? if [[ $stat -ne 0 ]]; then version="" else if [[ -n "$version" ]]; then if [[ "$version" == *"-FreeBSD"* ]]; then version=$(printf '%s' "$version" | head -n 1 | awk '{print $NF}' | sed 's|-FreeBSD||') else version=$(printf '%s' "$version" | head -n 1 | cut -d' ' -f4) fi fi fi result=$(printf "1\n1\n2\n" | $tool -m 1 "1" 2>/dev/null) if [[ "$result" == "1" ]]; then okstr="ok" if [[ -z "$version" ]]; then version="2.0"; fi else if [[ -z "$version" ]]; then version="1.0"; fi fi ;; base32) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f4) stat=$? if [[ $stat -ne 0 ]]; then version=""; fi ;; bash) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f4 | cut -d'(' -f1) stat=$? if [[ $stat -ne 0 ]]; then version=""; fi ;; tail | gtail) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f4 | cut -d'-' -f1) stat=$? if [[ $stat -ne 0 ]]; then version=""; fi result1=$(printf "1\n1\n2\n" | $tool -n 1 2>/dev/null) result2=$(printf "1\n1\n2\n" | $tool -n +2 2>/dev/null | tr '\n' ' ') if [[ "$result1" == "2" && "$result2" == "1 2 " ]]; then okstr="ok" if [[ -z "$version" ]]; then version="2.0"; fi else if [[ -z "$version" ]]; then version="1.0"; fi fi ;; tar) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f2) if [[ "$version" == "s:" ]]; then version="1.0" else if [[ "$version" == "(GNU" ]]; then version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f4) fi $tool cfz "${scratchfile}.tar.gz" "$script" 2>/dev/null stat=$? filecheck -rm "${scratchfile}.tar.gz" if [[ $stat -eq 0 ]]; then okstr="ok" if [[ -z "$version" ]]; then version="2.0"; fi else if [[ -z "$version" ]]; then version="1.0"; fi fi fi ;; find) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f2) if [[ "$version" == "(GNU" ]]; then version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f4) else touch "$scratchfile" resstr=$(find "$scratchfile" -type f -mmin -15 2>/dev/null) filecheck -rm "$scratchfile" if [[ "$resstr" == "$scratchfile" ]]; then okstr="ok" version="2.0" else version="1.0" fi fi ;; awk) version=$(printf '' | $tool --version 2>/dev/null | head -n 1 | cut -d' ' -f3 | sed 's|,$||') if [[ -z "$version" ]]; then version="1.0"; fi ;; sed | gsed) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f4) if [[ "$version" == "--" ]]; then version=""; fi result=$(printf "gnu-sed" | $tool 's|-\(.\)|\U\1|g' 2>/dev/null) if [[ "$result" == "gnuSed" ]]; then okstr="ok" if [[ -z "$version" ]]; then version="2.0"; fi else if [[ -z "$version" ]]; then version="1.0"; fi fi ;; java) javastring=$($tool -version 2>&1 | head -n 1) javaname=$(printf '%s' "$javastring" | cut -d' ' -f1) if [[ "$javaname" == "java" ]]; then javaname="OracleJava"; fi version=$(printf '%s' "$javastring" | cut -d'"' -f2 | tr '_' '.') ;; javac) javastring=$($tool -version 2>&1 | head -n 1) version=$(printf '%s' "$javastring" | cut -d' ' -f2 | tr '_' '.') ;; python* | pip* | easy_install* | curl) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f2 | cut -d'-' -f1) ;; zip) version=$($tool --help 2>/dev/null | head -n 2 | grep "^Zip" | cut -d' ' -f2) if [[ -z "$version" ]]; then version="1.0"; fi ;; unzip) version=$($tool --help 2>/dev/null | head -n 2 | sed 's|^Info-ZIP ||' | grep "^UnZip" | cut -d' ' -f2 | cut -d'-' -f1 | tr 'c' '.') ;; rclone) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f2 | sed 's|^v||') ;; terraform) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f2 | sed 's|^v||') ;; packer) file=$(filecheck -x file) if [[ -z "$file" ]]; then if [[ "$tool" == "/usr/sbin/packer" ]]; then str="cracklib-packer" else str="" fi else str=$($file "$tool" | grep "cracklib-packer") fi if [[ -n "$str" ]]; then printf '%s not found\n' "$cmd" exit 2 else version=$(printf '^d' | $tool --version 2>/dev/null | head -n 1 | cut -d' ' -f2 | sed 's|^v||') fi ;; jq) version=$($tool --version 2>/dev/null | head -n 1 | sed 's|^jq-||' | sed 's|^jq version ||') version=$(printf '%s' "$version" | cut -d'-' -f1) if [[ -z "$version" ]]; then version="1.5"; fi ;; wget | git | opc | puttygen) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f3) ;; tcsh) version=$($tool --version 2>/dev/null | head -n 1 | cut -d' ' -f2) ;; ansible) version=$($tool --version 2>/dev/null | head -n 1 | sed 's|\[core ||' | tr ']' ' ' | cut -d' ' -f2) ;; telnet) version="2.0" # dummy ;; nslookup) version=$(printf 'exit\n' | $tool -version 2>&1 | head -n 1 | cut -d' ' -f2 | cut -d'-' -f1) if [[ "$version" == "Invalid" ]]; then version="1.5"; fi ;; psm) version=$($tool --version 2>/dev/null) stat=$? if [[ $stat -eq 0 ]]; then if [[ "$OS" == "Darwin" ]]; then result=$(printf '%s' "$version" | grep '^using disk:') if [[ -n "$result" ]]; then description="need reinstallation ('Apple Silicon password slot manager' found instead of 'Oracle PaaS CLI client')" version="" else version=$(printf '%s' "$version" | head -n 2 | sed 's| - |\n|g' | grep -i 'version' | cut -d' ' -f2) fi else version=$(printf '%s' "$version" | head -n 2 | sed 's| - |\n|g' | grep -i 'version' | cut -d' ' -f2) fi else version="" fi ;; sdk) version=$($tool 2>/dev/null | head -n 1 | cut -d' ' -f2) ;; oci) version=$($tool --version 2>/dev/null | head -n 1) ;; *) version="unknown" ;; esac if [[ -n "$version" ]]; then if [[ -n "$minimum" ]]; then result=$(compare-version --quiet "$minimum" "$version") stat=$? if [[ $stat -gt 0 ]]; then version="unknown" okstr="need reinstallation" else if [[ "$result" == "same" || "$result" == "newer" ]]; then okstr="ok" else okstr="need $minimum" fi fi elif [[ -n "$maximum" ]]; then result=$(compare-version --quiet "$version" "$maximum") stat=$? if [[ $stat -gt 0 ]]; then version="unknown" okstr="need reinstallation" else if [[ "$result" == "same" || "$result" == "older" ]]; then okstr="ok" else okstr="greater $maximum" fi fi fi printf "%s %s %s\n" "$tool" "$version" "$okstr" else printf "%s %s %s\n" "$tool" "unknown" "$description" fi fi