Search code examples
bashshellvariablesquotes

Passing variables to a variable in bash


I'm writing custom logging for the bash:

#!/usr/bin/env bash

set -e +x

SCRIPT_LOG_NAME='[MYSCRIPT]'
SCRIPT_LOG_DATETIME_FORMAT="+%Y-%m-%d %H:%M:%S"
SCRIPT_LOG_LEVEL_INFO='INFO'
SCRIPT_LOG_PATTERN="${SCRIPT_LOG_NAME} $(date "${SCRIPT_LOG_DATETIME_FORMAT}") $1 : $2"

log_general() {
  ...
}

log_info() {
  log_general "$SCRIPT_LOG_LEVEL_INFO" "$1"
}

And I want to pass variables $SCRIPT_LOG_LEVEL_INFO and "$1" as parameters to the function log_general(). And use this parameters in the $SCRIPT_LOG_PATTERN to achive output:
[MYSCRIPT] 2023-01-01 10:10:10 INFO : Something logged

I tried something like:

log_general() {
  echo -e "$SCRIPT_LOG_PATTERN" "$1" "$2"
}

Or

SCRIPT_LOG_LEVEL=''
SCRIPT_LOG_PATTERN="${SCRIPT_LOG_NAME} $(date "${SCRIPT_LOG_DATETIME_FORMAT}") ${SCRIPT_LOG_LEVEL} : "

log_general() {
  SCRIPT_LOG_LEVEL=$SCRIPT_LOG_LEVEL_INFO
  echo -e "${SCRIPT_LOG_PATTERN}${1}"
}

log_info() {
  log_general "$1"
}

But I could not achieve the desired result. Can you help me, please?


Solution

  • If you'd like to use ${SCRIPT_LOG_PATTERN} as a global variable and later on substitute the ${1} and ${2} you would have to escape the $ sign and then evaluate the string later on in log_general.

    This would look something like this:

    #!/bin/bash
    
    set -e +x
    
    SCRIPT_LOG_NAME='[MYSCRIPT]'
    SCRIPT_LOG_DATETIME_FORMAT="+%Y-%m-%d %H:%M:%S"
    SCRIPT_LOG_LEVEL_INFO='INFO'
    SCRIPT_LOG_PATTERN="${SCRIPT_LOG_NAME} $(date "${SCRIPT_LOG_DATETIME_FORMAT}") \$1 : \$2"
    
    log_general() {
            eval echo "${SCRIPT_LOG_PATTERN}"
    }
    
    log_info() {
            log_general "${SCRIPT_LOG_LEVEL_INFO}" "${1}"
    }
    

    Usage:

    $ source logging_test.sh
    $ log_info "my custom message"
    [MYSCRIPT] 2023-06-02 14:03:27 INFO : my custom message
    
    

    I'd also recommend escaping the date command since otherwise the date will be parsed once, here is what I mean:

    $ log_info "asdads"; sleep 5; log_info "asdsad"
    [MYSCRIPT] 2023-06-02 14:06:28 INFO : asdads
    [MYSCRIPT] 2023-06-02 14:06:28 INFO : asdsad
    

    As you can see the time does not change even with 5 seconds of sleep.

    To fix this escape the date as well like this:

    SCRIPT_LOG_PATTERN="${SCRIPT_LOG_NAME} \$(date '${SCRIPT_LOG_DATETIME_FORMAT}') \$1 : \$2"
    

    Output now:

    $ log_info "asdads"; sleep 5; log_info "asdsad"
    [MYSCRIPT] 2023-06-02 14:09:19 INFO : asdads
    [MYSCRIPT] 2023-06-02 14:09:25 INFO : asdsad