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