Bash变量包含一组值中的一个值

Bash变量包含一组值中的一个值,bash,Bash,我正在开发一个“包装器脚本”,在Bash中用作“日志记录辅助” 它应该在调用调用时打印出有关调用堆栈的信息 我已经在这方面做了一些工作,如下所述,但仍有一些问题/疑问,我希望从这里的专家那里得到最好的答案 我的代码: 用法示例: 或: 我的疑问是: call_stack_position=$(call_stack_position++) 我想不出更好的方法来增加这个变量,有更好的/更可读的形式吗 我可以使用更好的构造来检测调用是否由日志方法进行吗?(例如跟踪、调试、信息…)。所有那些

我正在开发一个“包装器脚本”,在Bash中用作“日志记录辅助”

它应该在调用调用时打印出有关调用堆栈的信息

我已经在这方面做了一些工作,如下所述,但仍有一些问题/疑问,我希望从这里的专家那里得到最好的答案


我的代码:
用法示例: 或:


我的疑问是:
  • call_stack_position=$(call_stack_position++)
我想不出更好的方法来增加这个变量,有更好的/更可读的形式吗

  • 我可以使用更好的构造来检测调用是否由日志方法进行吗?(例如跟踪、调试、信息…)。所有那些
    if
    的话都让我的眼睛很痛

  • 我是否重新发明了轮子/滥用了我想学习的工具?(即shell脚本)

当然,我可能会重新发明轮子,但这是自我训练。。有一天不再做收费亭的夜班工人



我正在查找与指定的my_函数\u log_*名称匹配的项,而不查找其他项。假设我有这样的自由度是不合适的(如果有很多
正是出于这个原因,我在寻找一些语法糖或更好地使用语言功能来进行这种类型的“集合成员资格”测试)。

我可以为你的前两个问题提出这样的建议:

if [[ "${CALLER}" == my_function_log_* ]]
then 
  let call_stack_position++
fi
如果您只想在log\之后获得一组值:

if [[ "${CALLER}" =~ my_function_log_(trace|debug|info|warning|error|critical) ]]
then 
  let call_stack_position++
fi      

我可以为您的前两个问题提出以下建议:

if [[ "${CALLER}" == my_function_log_* ]]
then 
  let call_stack_position++
fi
如果您只想在log\之后获得一组值:

if [[ "${CALLER}" =~ my_function_log_(trace|debug|info|warning|error|critical) ]]
then 
  let call_stack_position++
fi      

进行增量的一种更具可读性的方法是在数值上下文中对其进行增量:

(( call_stack_position++ ))
对于匹配,可以在bash中使用glob:

[[ $CALLER == my_function_log_* ]]
至于改造轮子,您可以使用bash中的syslog日志记录,使用
logger
命令。本地syslog守护进程将处理格式化日志消息并将其写入文件

logger -p local0.info "CRITICAL Temporarily increasing energy level to 9001"
根据评论进行更新。您可以使用关联数组来更明确地说明您要查找的内容。它需要bashv4或更高版本

declare -A arr=(
    ['my_function_log_trace']=1
    ['my_function_log_debug']=1
    ['my_function_log_info']=1
    ['my_function_log_warning']=1
    ['my_function_log_error']=1
    ['my_function_log_critical']=1
);

if [[ ${arr[CALLER]} ]]; then
    ...
fi
您还可以使用扩展的globbing进行模式匹配,类似于perreal答案中的正则表达式,但没有正则表达式:

shopt -s extglob
if [[ $CALLER == my_function_log_@(trace|debug|info|warning|error|critical) ]]; then
    ...
fi

进行增量的一种更具可读性的方法是在数值上下文中对其进行增量:

(( call_stack_position++ ))
对于匹配,可以在bash中使用glob:

[[ $CALLER == my_function_log_* ]]
至于改造轮子,您可以使用bash中的syslog日志记录,使用
logger
命令。本地syslog守护进程将处理格式化日志消息并将其写入文件

logger -p local0.info "CRITICAL Temporarily increasing energy level to 9001"
根据评论进行更新。您可以使用关联数组来更明确地说明您要查找的内容。它需要bashv4或更高版本

declare -A arr=(
    ['my_function_log_trace']=1
    ['my_function_log_debug']=1
    ['my_function_log_info']=1
    ['my_function_log_warning']=1
    ['my_function_log_error']=1
    ['my_function_log_critical']=1
);

if [[ ${arr[CALLER]} ]]; then
    ...
fi
您还可以使用扩展的globbing进行模式匹配,类似于perreal答案中的正则表达式,但没有正则表达式:

shopt -s extglob
if [[ $CALLER == my_function_log_@(trace|debug|info|warning|error|critical) ]]; then
    ...
fi

Bash的类型系统,如果你想这样称呼它的话,是非常基本的:字符串和整数是它唯一的一类公民,数组是一个附加的想法,它的功能远不及Python集或Ruby数组。这就是说,对于依赖字符串匹配的数组,在
操作符中有一个穷人的
。给定一个函数名数组:

log_functions=(my_function_log_trace my_function_log_debug my_function_log_info my_function_log_warning my_function_log_error my_function_log_critical)
这:

将只匹配数组的成员。当我们谈论穷人的构造时,你可以将上面的模式与布尔控制算子结合到穷人的三元赋值中,从而完全跳过数值计算:

local -i call_stack_position=$([[ ${log_functions[*]} =~ \\b$CALLER\\b ]] && echo 1 || echo 2)
警告:在上,单词边界匹配需要使用更详细的字符类形式,即

[[ ${log_functions[*]} =~ [[:\<:]]$CALLER[[:\>:]] ]]
[${log\u函数[*]}=~[[:\:]]
注意:看到您的代码并注意到您提到您正在学习shell脚本,我将提供两个与问题无关的观察结果:

  • 变量扩展的大括号表示法仅用于数组访问、扩展操作和字符串连接中的变量名消歧。在其他情况下,即在测试和
    printf
    命令中都不需要它
  • 使用扩展字符串操作比使用外部操作快得多,因此建议尽可能使用扩展字符串操作。不要使用
    basename
    ,而是使用
    ${var##*/}

  • Bash的类型系统,如果你想这样称呼它的话,是非常基本的:字符串和整数是它唯一的一类公民,数组是一个附加的想法,它的功能远不及Python集或Ruby数组。这就是说,对于依赖字符串匹配的数组,在
    操作符中有一个穷人的
    。给定一个函数名数组:

    log_functions=(my_function_log_trace my_function_log_debug my_function_log_info my_function_log_warning my_function_log_error my_function_log_critical)
    
    这:

    将只匹配数组的成员。当我们谈论穷人的构造时,你可以将上面的模式与布尔控制算子结合到穷人的三元赋值中,从而完全跳过数值计算:

    local -i call_stack_position=$([[ ${log_functions[*]} =~ \\b$CALLER\\b ]] && echo 1 || echo 2)
    
    警告:在上,单词边界匹配需要使用更详细的字符类形式,即

    [[ ${log_functions[*]} =~ [[:\<:]]$CALLER[[:\>:]] ]]
    
    [${log\u函数[*]}=~[[:\:]]
    
    注意:看到您的代码并注意到您提到您正在学习shell脚本,我将提供两个与问题无关的观察结果:

  • 变量扩展的大括号表示法仅用于数组访问、扩展操作和字符串连接中的变量名消歧。在其他情况下,即在测试和
    printf
    命令中都不需要它
  • 使用扩展字符串操作比使用外部操作快得多,因此建议尽可能使用扩展字符串操作。不要使用
    basename
    ,而是使用
    ${var##*/}

  • 这是一个很好的适合,因为这是一个很好的适合,我感谢你的回答,但你所做的假设不是代码的一部分:我可以从一组可能的
    glob
    s中获取任何值,这是不正确的。我只能使用这些价值观,不能使用其他价值观。。(例如,在Pytho中设置成员身份)