User Tools

Site Tools


bash:bash_helper_script

The helper script

#####################################################################
# First Created: 15082025 Author: Allan Desc:
# supplies multiple functions that can help in creating bash scripts.
#
# For documentation and examples please see this link.
#
# https://wiki.x-files.dk/doku.php?id=linux:bash_helper_howto
#
#####################################################################
 
#
# Are we root if not die
#
must_be_root() {
    local required="$1"
 
    if [[ "$required" == "yes" ]]; then
        if [[ $UID -ne 0 ]]; then
            printf "\nThis script must be run as root or use sudo\n\n"
            exit 1
        fi
    fi
}
 
#
# Are we in the right directory if not die
#
must_be_in_dir() {
    local required_dir="$1"
    if [[ "${PWD##*/}" != "$required_dir" ]]; then
        printf "\nWrong directory! This script must be run from the directory '%s'\n\n" "$required_dir"
        exit 1
    fi
}
 
# 
# Checks if a service is running or not and react accordingly
#
servicecheck() {
    local mode="$1"
    shift
    local bad_services=()
 
    case "$mode" in
        dead)
            for service in "$@"; do
                if [[ "$(systemctl is-active "$service")" != "active" ]]; then
                    bad_services+=("$service")
                fi
            done
            if (( ${#bad_services[@]} > 0 )); then
                echo "The following service(s) appears not to be running cannot continue..."
                for svc in "${bad_services[@]}"; do
                    echo "  - $svc"
                done
                exit 1
            fi
            ;;
        alive)
            for service in "$@"; do
                if [[ "$(systemctl is-active "$service")" == "active" ]]; then
                    bad_services+=("$service")
                fi
            done
            if (( ${#bad_services[@]} > 0 )); then
                echo "The following service(s) appears already to be running cannot continue..."
                for svc in "${bad_services[@]}"; do
                    echo "  - $svc"
                done
                exit 1
            fi
            ;;
    esac
}
 
#
# Detect input mode: "flags" or "positional" this will detect whether $1 or getopts is beeing used.
#
detect_mode() {
    for arg in "$@"; do
        if [[ "$arg" == -* ]]; then
            echo "flags"
            return
        fi
    done
    echo "positional"
}
 
#
# Print usage dynamically (adapts to mode)
#
usage() {
    local mode
    mode=$(detect_mode "$@")
 
    printf "Usage: %s " "$0"
 
    if [[ $mode == "flags" ]]; then
        printf "[options]\n"
        for flag in "${flags[@]}"; do
            short="${flag%%:*}"
            rest="${flag#*:}"
            desc="${rest#*:}"
            desc="${desc%%:*}"
            printf "  -%s  %s\n" "$short" "$desc"
        done
        printf "  -h  Show help\n\n"
 
        printf "Example:\n"
        example="$0"
        for flag in "${flags[@]}"; do
            short="${flag%%:*}"
            rest="${flag#*:}"          # remove short
            rest="${rest#*:}"          # remove var
            desc="${rest%%:*}"         # description
            rest="${rest#*:}"
            sample="${rest%%:*}"
            example+=" -$short ${sample:-$desc}"
        done
        printf "%s\n\n" "$example"
 
    else
        # positional usage
        for flag in "${flags[@]}"; do
            rest="${flag#*:}"
            var="${rest%%:*}"
            rest="${rest#*:}"
            desc="${rest%%:*}"
            rest="${rest#*:}"
            sample="${rest%%:*}"
            required="${flag##*:}"
 
            if [[ "$required" == "true" ]]; then
                printf "<%s> " "$desc"
            else
                printf "[%s] " "$desc"
            fi
        done
        printf "\n\n"
 
        printf "Example:\n"
        example="$0"
        for flag in "${flags[@]}"; do
            rest="${flag#*:}"      # remove short
            rest="${rest#*:}"      # remove var
            desc="${rest%%:*}"
            rest="${rest#*:}"
            sample="${rest%%:*}"
            example+=" ${sample:-$desc}"
        done
        printf "%s\n\n" "$example"
    fi
}
 
#
# Validate required input (works in both modes)
#
validate_input() {
    local mode
    mode=$(detect_mode "$@")
    local missing=false
    local i=1
 
    for flag in "${flags[@]}"; do
        short="${flag%%:*}"
        rest="${flag#*:}"
        var="${rest%%:*}"
        rest="${rest#*:}"
        desc="${rest%%:*}"
        rest="${rest#*:}"
        sample="${rest%%:*}"
        required="${flag##*:}"
 
        value="${!var}"
 
        if [[ -z "$value" && $mode == "positional" ]]; then
            value="${!i}"
            if [[ -n "$value" ]]; then
                printf -v "$var" '%s' "$value"
            fi
        fi
 
        if [[ "$required" == "true" && -z "${!var}" ]]; then
            printf "Error! %s is empty.\n" "$desc"
            missing=true
        fi
        ((i++))
    done
 
    if [[ $missing == true ]]; then
        printf "\n"
        usage "$@"
        exit 1
    fi
}
bash/bash_helper_script.txt · Last modified: by 127.0.0.1