# Bash ## stdout/stderr (console and logs) ``` bash #!/usr/bin/env bash # Environment overrides LOG_LEVEL="${LOG_LEVEL:-INFO}" # TRACE, DEBUG, INFO, WARN, ERROR LOG_INCLUDE_TS=0 # 0 or 1 = include timestamp LOG_INCLUDE_TYPE=1 # 0 or 1 = include [LEVEL] # When set to 1, all log messages are sent to stderr instead of splitting # INFO/DEBUG/TRACE to stdout and WARN/ERROR to stderr. Useful for scripts # where stdout must remain clean for pipelines, JSON output, or data export. LOG_ALL_TO_STDERR=0 # Level mapping declare -A LEVELS=([TRACE]=0 [DEBUG]=1 [INFO]=2 [WARN]=3 [ERROR]=4) # Helpers _log_ts() { [ "$LOG_INCLUDE_TS" = "1" ] && printf "[%s]" "$(date -Iseconds)"; } _log_type() { [ "$LOG_INCLUDE_TYPE" = "1" ] && printf "[%s]" "$1"; } _log_ok() { [[ ${LEVELS[$1]} -ge ${LEVELS[$LOG_LEVEL]} ]]; } # Output selector _log_out() { local level="$1" shift local msg="$*" if [ "$LOG_ALL_TO_STDERR" = "1" ]; then printf "%s\n" "$msg" >&2 else case "$level" in TRACE|DEBUG|INFO) printf "%s\n" "$msg" >&1 ;; WARN|ERROR) printf "%s\n" "$msg" >&2 ;; esac fi } # Log functions log_trace() { _log_ok TRACE && _log_out TRACE "$(_log_ts)$(_log_type TRACE) $*"; } log_debug() { _log_ok DEBUG && _log_out DEBUG "$(_log_ts)$(_log_type DEBUG) $*"; } log_info() { _log_ok INFO && _log_out INFO "$(_log_ts)$(_log_type INFO) $*"; } log_warn() { _log_ok WARN && _log_out WARN "$(_log_ts)$(_log_type WARN) $*"; } log_error() { _log_ok ERROR && _log_out ERROR "$(_log_ts)$(_log_type ERROR) $*"; } # Examples log_trace "trace example" log_debug "debug example" log_info "info example" log_warn "warn example" log_error "error example" log_error "error example" ``` ## arrays ``` bash # creates an array variable ORPHANS=() # checks length if [[ ${#ORPHANS[@]} -eq 0 ]]; then echo "No orphans found." else echo "orphans:" printf "%s\n" "${ORPHANS[@]}" fi ``` ## associative array an data structure that lets you store key → value pairs ``` bash # clean if already been used unset PV_PATHS # declare an associative array, an data structure that lets you store key → value pairs declare -A PV_PATHS for name in $(kubectl get pv -o jsonpath='{.items[*].metadata.name}'); do path=$(kubectl get pv ${name} -o jsonpath='{.spec.local.path}' 2>/dev/null) # check if path is no empty [[ -n "${path}" ]] && PV_PATHS["${name}"]="${path}" done # print only keys echo echo "All Keys:" printf "%s\n" "${!PV_PATHS[@]}" echo echo "All Values:" # print only values printf "%s\n" "${PV_PATHS[@]}" echo echo "Keys|Values:" # print all for key in "${!PV_PATHS[@]}"; do printf "%s|%s\n" "$key" "${PV_PATHS[$key]}" done ``` ## misc ```bash #!/bin/bash script_directory="$(dirname "$(readlink -f "$0")")" #simbolo para comentário if ; then fi if test $variavel -eq 3; then echo fi if [ $variavel -eq 3 ]; then echo fi if [ ! $variavel -eq 3 ]; then echo fi if [ $variavel -eq 3 -a $variavel -eq 2 -o $variavel -eq 1]; then echo fi `` #!/bin/bash function echoArguments(){ echo "printing ($#) arguments" for ARGUMENT in "$@" do echo $ARGUMENT done } echoArguments $@ Também é possível aceder por índice #!/bin/bash function echoArguments(){ echo "$0" echo "$1" } echoArguments $@ Testar se um programa está a correr if pgrep jivelite>/dev/null then echo "a correr" else echo "nao esta correr" fi verifica o numero de parametros cuidado tem que ter mesmo os espaços nos parenteses rectos if [ "$#" -ne 2 ] then echo "wrong number of parameters($#)" echo "0 - name of processo to search" echo "1 - commando to start" exit 1 fi ``