#!/usr/bin/env bash # # Author: Georg Voell - georg.voell@standby.cloud # Version: @(#)errormsg 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. # #@ Prints an error message in red color to stderr. #@ This script can be called with 2 or 3 parameters. #@ If "LOGFILE" is defined, it writes error message also to log. #@ First parameter is the error number. #@ Second parameter is the error message. #@ Third (optional) parameter is the error reason. #@ #@Usage: errormsg [options] errnum errmsg [errrsn] #@ Options: #@ -h, --help : Displays helptext. #@ -v, --version: Displays the version of the script. #@ -q, --quiet : Just write error message to LOGFILE. #@ ErrNum: Number between 1 and 99. 0 for Warning messages #@ ErrMsg: Error message to be displayed. #@ ErrRsn: Optional: Error reason. #@ #@Examples: #@ errormsg 0 "No internet connection." #@ Will display the warning message "WARNING: No internet connection." to stderr. #@ errormsg 1 "No 'curl' in PATH." #@ Will display the error message "ERROR(01): No 'curl' in PATH." to stderr. #@ errormsg 2 "No internet connection." "No connection to external server" #@ Will display "ERROR(02): No insternet connection. (No connection to external server)" to stderr. #@ export LOGFILE="${HOME}/test.log"; errormsg -q 3 "Can't delete file." #@ Will write "2020-06-01 14:37:51 ERROR(03): Can't delete file." to $LOGFILE. # # Exit codes: # 01: Unknown or wrong parameter. # 02: Could not create logfile. # 03: Could not write to logfile. # # See also: # **install-scripts**(1) # # Update history: # # V 1.0.0 26.10.2017 New version # V 2.0.0 05.07.2019 Minor changes # V 3.0.0 24.04.2020 Adding plausibility checks # V 3.0.1 01.06.2020 Display help and version # V 3.0.2 11.06.2020 Using library # V 3.0.3 02.07.2020 Version was not shown by option --version # V 3.0.4 14.10.2020 Diplay a WARNING message with errnum = 0 # V 3.1.0 05.06.2023 New copyright # V 3.2.0 26.08.2024 New minor version # V 3.2.1 05.09.2025 Write to /dev/tty if /dev/stderr is not writable # 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 number check with [[ =~ ]]; 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 # Print errormsg to /dev/stderr function DisplayError() { local number="${1}" # Error Number local errmsg="${2}" # Error Message local errrsn="${3}" # Error Reason local output="" # Check if /dev/stderr is writable if [[ -w /dev/stderr ]]; then output=/dev/stderr else output=/dev/tty fi # Display error message if (( number == 0 )); then printf "${pink}WARNING: %s${normal}\n" "$errmsg" >> "$output" else if [[ -z "$errrsn" ]]; then printf "${highred}ERROR(%02d): %s${normal}\n" "$number" "$errmsg" >> "$output" else printf "${highred}ERROR(%02d): %s (%s)${normal}\n" "$number" "$errmsg" "$errrsn" >> "$output" fi fi } # Preset curdate=$(date "+%Y-%m-%d %T") # For use in logfiles, etc. quiet=false # true to suppress error messages errnum="" errarg="" erropt="" # Check parameters: Loop until all parameters are used up while [[ $# -gt 0 ]]; do pname="${1}" case "$pname" in -v | --version) shift showversion=true ;; -h | --help) shift showhelp=true ;; -q | --quiet) shift quiet=true ;; *) shift # Use bash pattern match instead of echo|grep subshell if [[ "$pname" == -* ]]; then errstr="Unknown option '$pname'." else if [[ -z "$errnum" ]]; then errnum="$pname" elif [[ -z "$errarg" ]]; then errarg="$pname" elif [[ -z "$erropt" ]]; then erropt="$pname" else errstr="Unknown parameter: '$pname'." fi fi ;; esac done # Plausibility checks if [[ -z "$errarg" ]]; then errstr="Please call '$progstr' with 2 or 3 parameters." else if [[ -n "$errnum" ]]; then # Use bash regex instead of echo|grep subshell if [[ "$errnum" =~ ^[0-9]+$ ]]; then if (( errnum < 0 || errnum > 99 )); then errstr="First parameter has to be between 0 and 99 (was '$errnum')." fi else errstr="First parameter is not a number (was '$errnum')." fi fi fi # Display help or error message DisplayHelp # Write to logfile if it is defined e.g. export LOGFILE="./test.log" stat=0 # 0 = Everything ok if [[ -n "$LOGFILE" ]]; then # Check if $LOGFILE exists - otherwise create it if [[ ! -f "$LOGFILE" ]]; then touch "$LOGFILE" > /dev/null 2>&1 stat=$? fi # Check if we can access $LOGFILE if [[ $stat -eq 0 ]]; then if [[ -f "$LOGFILE" ]]; then if (( errnum == 0 )); then printf "%s WARNING: %s\n" "$curdate" "$errarg" >> "$LOGFILE" 2>&1 elif [[ -z "$erropt" ]]; then printf "%s ERROR(%02d): %s\n" "$curdate" "$errnum" "$errarg" >> "$LOGFILE" 2>&1 stat=$? else printf "%s ERROR(%02d): %s (%s)\n" "$curdate" "$errnum" "$errarg" "$erropt" >> "$LOGFILE" 2>&1 stat=$? fi else stat=1 fi if [[ $stat -ne 0 ]]; then exitcode=3 if [[ -z "$erropt" ]]; then erropt="${progstr}: Could not write to logfile '$LOGFILE'" else erropt="${erropt} - ${progstr}: Could not write to logfile '$LOGFILE'" fi fi else exitcode=2 if [[ -z "$erropt" ]]; then erropt="${progstr}: Could not create logfile '$LOGFILE'" else erropt="${erropt} - ${progstr}: Could not create logfile '$LOGFILE'" fi fi fi # Call local function if [[ "$quiet" == false ]]; then DisplayError "$errnum" "$errarg" "$erropt" fi # Exit with exitcode exit $exitcode