使用FUNCNAME和BASH_LINENO实现shell脚本中定位函数错误在代码中的位置
#!/bin/bash
# 日志打印
LOG()
{
# 这就是教训,单引号无法进行解析变量值,需要双引号
echo 'BASH_LINENO: ${BASH_LINENO}'
echo '${BASH_LINENO}'
echo ${BASH_LINENO}
echo '~~~~~~~~~~~~~~~~~~~~~~~~~~'
echo "BASH_LINENO: ${BASH_LINENO}"
echo "FUNCNAME : ${FUNCNAME}"
echo "MODULE_PID : ${MODULE_PID}"
echo "MODULE_NAME: ${MODULE_NAME}"
echo "@ : $@"
echo '--------------------------'
echo "${BASH_LINENO[0]}:${FUNCNAME[1]} $@" | logger -t "${MODULE_NAME}(${MODULE_PID})"
echo '##########################'
}
LOG 'xinput map-to-output device to hdmi'
echo "BASH_LINENO: ${BASH_LINENO[0]}"
echo "FUNCNAME : ${FUNCNAME[0]}"
echo "MODULE_PID : ${MODULE_PID}"
echo "MODULE_NAME: ${MODULE_NAME}"
echo "@ : $@"
test_log()
{
echo "BASH_LINENO: ${BASH_LINENO}"
echo "FUNCNAME : ${FUNCNAME}"
echo "MODULE_PID : ${MODULE_PID}"
echo "MODULE_NAME: ${MODULE_NAME}"
echo "@ : $@"
echo "总共有 ${#FUNCNAME[@]} 个函数调用."
echo "总共有 ${#BASH_LINENO[@]} 个不同的行数."
func_cnt=${#FUNCNAME[@]}
for((i=0; i<func_cnt; i++)); do
echo ${FUNCNAME[$i]} ${BASH_LINENO[$i]}
done
}
func1()
{
echo "I am func1"
test_log
}
func2()
{
echo "I am func2"
func1
test_log
}
func2 "arg1" "arg2"
输出结果:
BASH_LINENO: ${BASH_LINENO}
${BASH_LINENO}
26
~~~~~~~~~~~~~~~~~~~~~~~~~~
BASH_LINENO: 26
FUNCNAME : LOG
MODULE_PID :
MODULE_NAME:
@ : xinput map-to-output device to hdmi
--------------------------
##########################
BASH_LINENO: 0
FUNCNAME : main
MODULE_PID :
MODULE_NAME:
@ :
I am func2
I am func1
BASH_LINENO: 56
FUNCNAME : test_log
MODULE_PID :
MODULE_NAME:
@ :
总共有 4 个函数调用.
总共有 4 个不同的行数.
test_log 56
func1 62
func2 66
main 0
BASH_LINENO: 63
FUNCNAME : test_log
MODULE_PID :
MODULE_NAME:
@ :
总共有 3 个函数调用.
总共有 3 个不同的行数.
test_log 63
func2 66
main 0
终于明白logger命令使用后为啥什么都没有,原来是日志输出到vim /var/log/syslog文件中去了。
特点
BASH_LINENO显示函数调用的位置行数
logger
logger是一个shell命令接口,可以通过该接口使用Syslog的系统日志模块,还可以从命令行直接向系统日志文件写入一行信息。
**options (选项):**
-d, --udp
使用数据报(UDP)而不是使用默认的流连接(TCP)
-i, --id
逐行记录每一次logger的进程ID
-f, --file file_name
记录特定的文件
-h, --help
显示帮助文本并退出
-n, --server
写入指定的远程syslog服务器,使用UDP代替内装式syslog的例程
-s, --stderr
输出标准错误到系统日志。
-t, --tag tag
指定标记记录
-u, --socket socket
写入指定的socket,而不是到内置系统日志例程。
-V, --version
显示版本信息并退出
-P, --port port_num
使用指定的UDP端口。默认的端口号是514
-p, --priority priority_level
指定输入消息日志级别,优先级可以是数字或者指定为 " facility.level" 的格式。
日志成型
#!/bin/bash
# 日志打印
LOG()
{
echo "`date` ${FUNCNAME[1]}:${BASH_LINENO[0]} $@"
}
LOG "hello world!"