在 bash 中将变量传递给变量

Passing variables to a variable in bash

提问人:Michael Linker 提问时间:6/2/2023 最后编辑:Michael Linker 更新时间:6/2/2023 访问量:49

问:

我正在为 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"
}

我想将变量和参数传递给函数。并在 实现输出中使用此参数:$SCRIPT_LOG_LEVEL_INFO"$1"log_general()$SCRIPT_LOG_PATTERN
[MYSCRIPT] 2023-01-01 10:10:10 INFO : Something logged

我尝试了这样的东西:

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

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"
}

但我无法达到预期的结果。你能帮帮我吗?

Bash shell 变量 行情

评论

0赞 user1934428 6/2/2023
您在设置SCRIPT_LOG_PATTERN时已经输入了日期是没有意义的。通过这样做,您将在每次调用时记录完全相同的日期。log_general

答:

1赞 Ivan 6/2/2023 #1

尝试:printf

pattern="%s $(date "${SCRIPT_LOG_DATETIME_FORMAT}") %s : %s"

log_general() {
    printf -v SCRIPT_LOG_PATTERN "$pattern" "$1" "$2" "$3"
}

用法:

log_general "$SCRIPT_LOG_NAME" "$1" "$2"

此函数将使用 $pattern 变量设置 $SCRIPT_LOG_PATTERN 变量,所有 '%s' 都将相应地更改为提供的值。

1赞 Arslan Sohail Bano 6/2/2023 #2

如果您想用作全局变量,稍后再替换 和 ,则必须转义该符号,然后稍后在 中计算字符串。${SCRIPT_LOG_PATTERN}${1}${2}$log_general

这看起来像这样:

#!/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}"
}

用法:

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

我还建议转义该命令,否则日期将被解析一次,这就是我的意思:date

$ 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

如您所见,即使睡眠 5 秒,时间也不会改变。

要解决此问题,也要像这样:date

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

现在输出:

$ 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

评论

0赞 Arslan Sohail Bano 6/2/2023
不久前,我为 bash 创建了一个小型记录器,也许它可以帮助您获得一些想法或帮助您改进自己的记录器: gist.github.com/ArslanSB/92663e81e5128d1fc3b9ef053f08852e