3 Star 0 Fork 1

Gitee 极速下载/log4sh

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/kward/log4sh
克隆/下载
log4sh_base 18.16 KB
一键复制 编辑 原始数据 按行查看 历史
Kate Ward 提交于 2018-01-18 05:27 +08:00 . Updated copyright and license info.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
# vim:et:ft=sh:sts=2:sw=2
#
# Copyright 2008-2018 Kate Ward. All Rights Reserved.
# Released under the Apache License 2.0 license.
#
# Logging framework 4 SHell scripts
# https://github.com/kward/log4sh
#
# Author: [email protected] (Kate Ward)
#
# This module implements something like the log4j module from the Apache group.
# return if log4sh already loaded
[ -z "${LOG4SH_VERSION:-}" ] || return
LOG4SH_VERSION='1.5.1pre'
#
# constants
#
LOG4SH_TRUE=0
LOG4SH_FALSE=1
LOG4SH_ERROR=2
[ -z "${LOG4SH_LOG_FILE:-}" ] && LOG4SH_LOG_FILE=''
__LOG4SH_LOGGER_ROOT='root'
__LOG4SH_LEVEL_TRACE='TRACE'
__LOG4SH_LEVEL_DEBUG='DEBUG'
__LOG4SH_LEVEL_INFO='INFO'
__LOG4SH_LEVEL_WARN='WARN'
__LOG4SH_LEVEL_ERROR='ERROR'
__LOG4SH_LEVEL_FATAL='FATAL'
__LOG4SH_KV_TYPE='type'
#
# global variables -- see also log4sh_resetConfiguration()
#
__log4sh_appenders='' # list of valid appenders
__log4sh_dictFile='' # internal dictionary of key/value pairs
__log4sh_tmpDir='' # temporary directory
__log4sh_trapsFile='' # previously defined traps
#
# macros
#
_LOG4SH_LINENO_='eval log4sh_lineno_=""; if [ "${1:-}" = "--lineno" ]; then [ -n "$2" ] && log4sh_lineno_="$2"; shift 2; fi'
# wrappers for interal logging to include line numbers
_LOG4SH_DEBUG_='eval _log4sh_debug --lineno "${LINENO:-}"'
_LOG4SH_INFO_='eval _log4sh_info --lineno "${LINENO:-}"'
_LOG4SH_ERROR_='eval _log4sh_error --lineno "${LINENO:-}"'
# Split fully qualified [logger.]appender string and set local variables.
#
# This function sets the following variables:
# log4sh_logger_: string: logger name; empty if none
# log4sh_appender_: string: appender name
#
# Args:
# fqla: string: fully qualified [logger.]appender
_LOG4SH_SPLIT_LOGGER_APPENDER_='eval expr "$1" : ".*\..*" >/dev/null; if [ $? -eq 0 ]; then log4sh_logger_=`expr "$1" : "\(.*\)\..*"`; log4sh_appender_=`expr "$1" : ".*\.\(.*\)"`; else log4sh_logger_=${__LOG4SH_LOGGER_ROOT}; log4sh_appender_=$1; fi; log4sh_fqAppender_="${log4sh_logger_}.${log4sh_appender_}"; shift'
_LOG4SH_CLEANUP_LOGGER_APPENDER_='eval unset log4sh_appender_ log4sh_fqAppender_ log4sh_logger_'
#-----------------------------------------------------------------------------
# log4sh functions
#
# Common logging function for log4sh itself.
#
# Args:
# level: string: logging level (e.g. INFO)
# message: string: message to log
_log4sh_log()
{
_log4sh_lineno_=$1
_log4sh_level_=$2
shift 2
[ -n "${_log4sh_lineno_:-}" ] && _log4sh_lineno_="[${_log4sh_lineno_}]"
_log4sh_message_="${_log4sh_level_}${_log4sh_lineno_} $@"
if [ -z "${LOG4SH_LOG_FILE}" ]; then
echo "log4sh:${_log4sh_message_}" >&2
else
echo "${_log4sh_message_}" >>"${LOG4SH_LOG_FILE}"
fi
unset _log4sh_level_ _log4sh_lineno_ _log4sh_message_
}
# DEBUG level logging function for log4sh.
#
# Args:
# message: string: message to log
_log4sh_debug()
{
${_LOG4SH_LINENO_}
_log4sh_log "${log4sh_lineno_}" ${__LOG4SH_LEVEL_DEBUG} "$@"
unset log4sh_lineno_
}
# INFO level logging function for log4sh.
#
# Args:
# message: string: message to log
_log4sh_info()
{
${_LOG4SH_LINENO_}
_log4sh_log "${log4sh_lineno_}" ${__LOG4SH_LEVEL_INFO} "$@"
unset log4sh_lineno_
}
# ERROR level logging function for log4sh.
#
# Args:
# message: string: message to log
_log4sh_error()
{
${_LOG4SH_LINENO_}
_log4sh_log "${log4sh_lineno_}" ${__LOG4SH_LEVEL_ERROR} "$@"
unset log4sh_lineno_
}
# Cleanup function to remove the temporary directory used by log4sh.
#
# If there was a previously defined trap for the given signal, log4sh will
# attempt to call the original trap handler as well so as not to break the
# parent script.
#
# Args:
# trap: string: a trap signal (e.g. EXIT)
_log4sh_cleanup()
{
_log4sh_trap_=$1
_log4sh_restoreTrap_=${LOG4SH_FALSE}
_log4sh_oldTrap_=''
# match trap to signal value
case "${_log4sh_trap_}" in
EXIT) _log4sh_signal_=0 ;;
INT) _log4sh_signal_=2 ;;
TERM) _log4sh_signal_=15 ;;
esac
# do we possibly need to restore a previous trap?
if [ -r "${__log4sh_trapsFile}" -a -s "${__log4sh_trapsFile}" ]; then
# yes. figure out what we need to do
if [ `grep "^trap -- " "${__log4sh_trapsFile}" >/dev/null; echo $?` -eq 0 ]
then
# newer trap command
${_LOG4SH_DEBUG_} 'newer POSIX trap command'
_log4sh_restoreTrap_=${LOG4SH_TRUE}
_log4sh_oldTrap_=`egrep "(${_log4sh_trap_}|${_log4sh_signal_})$" \
"${__log4sh_trapsFile}" |sed "s/^trap -- '\(.*\)' [A-Z]*$/\1/"`
elif [ `grep "[0-9]*: " "${__log4sh_trapsFile}" >/dev/null; echo $?` -eq 0 ]
then
# older trap command
${_LOG4SH_DEBUG_} 'older style trap command'
_log4sh_restoreTrap_=${LOG4SH_TRUE}
_log4sh_oldTrap_=`grep "^${_log4sh_signal_}: " "${__log4sh_trapsFile}" |\
sed 's/^[0-9]*: //'`
else
# unrecognized trap output
_log4sh_error 'unable to restore old traps! unrecognized trap command output'
fi
fi
# do our work
rm -fr "${__log4sh_tmpDir}"
# execute the old trap
if [ ${_log4sh_restoreTrap_} -eq ${LOG4SH_TRUE} -a -n "${_log4sh_oldTrap_}" ]
then
${_LOG4SH_DEBUG_} "'restoring previous trap for (${_log4sh_trap_}) signal'"
eval "${_log4sh_oldTrap_}"
fi
# exit for all non-EXIT signals
if [ "${_log4sh_trap_}" != 'EXIT' ]; then
${_LOG4SH_WARN_} "'trapped and now handling the (${_log4sh_trap}) signal'"
# disable the EXIT trap
trap 0
# add 128 to signal value and exit
_log4sh_signal=`expr ${_log4sh_signal_} + 128`
exit ${_log4sh_signal_}
fi
unset _log4sh_oldTrap_ _log4sh_signal_ _log4sh_restoreTrap_ _log4sh_trap_
return
}
# Create a secure temporary directory.
#
# This function honors the TMPDIR environment variable if set.
#
# Args:
# none
# Outputs:
# string: path to temporary directory
# Returns:
# integer: success of operation
_log4sh_mktempDir()
{
_log4sh_tmpPrefix_='log4sh'
# try the standard mktemp function
( exec mktemp -dqt ${_log4sh_tmpPrefix_}.XXXXXX 2>/dev/null ) && return
# the standard mktemp didn't work. doing our own.
if [ -r '/dev/urandom' ]; then
_log4sh_random_=`od -vAn -N4 -tx4 </dev/urandom |sed 's/^[^0-9a-f]*//'`
elif [ -n "${RANDOM:-}" ]; then
# $RANDOM works
_log4sh_random_=${RANDOM}${RANDOM}${RANDOM}$$
else
# could not get a random number; generating one as best we can
_log4sh_date_=`date '+%Y%m%d%H%M%S'`
_log4sh_random_=`expr ${_log4sh_date_} / $$`
unset _log4sh_date_
fi
_log4sh_tmpDir_="${TMPDIR:-/tmp}/${_log4sh_tmpPrefix_}.${_log4sh_random_}"
( umask 077 && mkdir "${_log4sh_tmpDir_}" ) || {
_log4sh_fatal 'could not create temporary directory! exiting'
exit 1
}
${_LOG4SH_DEBUG_} "'created temporary directory (${_log4sh_tmpDir_})'"
echo "${_log4sh_tmpDir_}"
unset _log4sh_random_ _log4sh_tmpDir_ _log4sh_tmpPrefix_
return ${LOG4SH_TRUE}
}
# Common appender registration.
#
# This function must be called to register an appender with the log4sh
# framework so that appender specific functionality can be used.
#
# Args:
# appender: string: name of the appender type
_log4sh_register_appender()
{
_log4sh_appender_=$1
__log4sh_appenders="${__log4sh_appenders} ${_log4sh_appender_}"
_appender_register_${_log4sh_appender_} # call registration callback
# TODO: handle failure
unset _log4sh_appender_
}
# Append an element to end of list stored in a variable.
#
# As this function is used only internally, it expects the variable to be
# present. No error checking is done.
#
# Args:
# varname: string: name of variable containing list to be appended to
# data: string: data to be appended
_log4sh_listAppend()
{
_log4sh_varName_=$1
_log4sh_newData_=$2
_log4sh_strToEval_="_log4sh_data_=\${${_log4sh_varName_}}"
eval "${_log4sh_strToEval_}"
eval ${_log4sh_varName_}="'${_log4sh_data_:+${_log4sh_data_} }${_log4sh_newData_}'"
unset _log4sh_data_ _log4sh_newData_ _log4sh_strToEval_ _log4sh_varName_
}
# Get internal dictionary value.
#
# Args:
# unnamed_key: string: dictionary key (no spaces allowed)
# Outputs:
# value: string: dictionary value
# Returns:
# integer: success of operation
_log4sh_getValue()
{
if [ $# -ne 1 ]; then
${_LOG4SH_ERROR_} "'_log4sh_getValue(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
# 0=true, 1=false
set -x
echo 'dict file:' >&2
cat "${__log4sh_dictFile}" >&2
awk 'BEGIN{found=1}$1==key{print $2;found=0}END{exit found}' key=$1 \
"${__log4sh_dictFile}"
log4sh_return=$?
set +x
return ${log4sh_return}
}
# Set internal dictionary value.
#
# Args:
# key: string: dictionary key
# value: string: dictionary value
# Returns:
# integer: success of operation
_log4sh_setValue()
{
if [ $# -ne 2 ]; then
${_LOG4SH_ERROR_} "'_log4sh_setValue(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
_log4sh_key_=$1
_log4sh_value_=$2
sed -i '' "/^${_log4sh_key_} /d" "${__log4sh_dictFile}"
echo "${_log4sh_key_} ${_log4sh_value_}" >>"${__log4sh_dictFile}"
unset _log4sh_key_ _log4sh_value_
return ${LOG4SH_TRUE} # TODO(20090216:kward): check for some errors?
}
# Add a new logger.
#
# Args:
# logger: string: name of logger
# Returns:
# integer: success of the operation
log4sh_addLogger()
{
if [ $# -ne 1 ]; then
${_LOG4SH_ERROR_} "'log4sh_addLogger(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
log4sh_logger_=$1
_logger_isValid "${log4sh_logger_}"
if [ $? -eq ${LOG4SH_FALSE} ]; then
__log4sh_loggers="${__log4sh_loggers} ${log4sh_logger_}"
eval __log4sh_logger_${log4sh_logger_}=''
log4sh_return=${LOG4SH_TRUE}
else
${_LOG4SH_ERROR_} "'logger already exists (${log4sh_logger_})'"
log4sh_return=${LOG4SH_FALSE}
fi
unset log4sh_logger_
return ${log4sh_return}
}
# Reset log4sh to initial defaults.
#
# This function leaves dangingling bits all over the place. It resets just
# enough of the environment so that log4sh forgets about its past.
#
# Args:
# none
log4sh_resetConfiguration()
{
if [ -n "${__log4sh_loggers:-}" ]; then
for log4sh_logger_ in ${__log4sh_loggers}; do
${_LOG4SH_DEBUG_} "log4sh_logger_=${log4sh_logger_}"
done
fi
cp /dev/null "${__log4sh_dictFile}" # purge dictionary
__log4sh_loggers=''
log4sh_addLogger "${__LOG4SH_LOGGER_ROOT}"
unset log4sh_logger_
}
#------------------------------------------------------------------------------
# logger functions
#
# Determine if named logger is valid.
#
# Note: if this function is called from a private function, it must be done
# inside a subshell like (...;) due to variable scoping.
#
# Args:
# logger: string: name of logger
# Returns:
# boolean: validity of logger
_logger_isValid()
{
_log4sh_logger_=$1
_log4sh_isValid_=${LOG4SH_FALSE}
for _log4sh_validLogger_ in ${__log4sh_loggers}; do
if [ "${_log4sh_logger_}" = "${_log4sh_validLogger_}" ]; then
_log4sh_isValid_=${LOG4SH_TRUE}
break
fi
done
log4sh_return=${_log4sh_isValid_}
unset _log4sh_logger_ _log4sh_isValid_ _log4sh_validLogger_
return ${log4sh_return}
}
# Add a new appender to a logger.
#
# Args:
# appender: string: name of appender
# logger: string: name of logger to add appender to (optional)
# Returns:
# integer: success of the operation
logger_addAppender()
{
if [ $# -eq 0 -o $# -gt 2 ]; then
${_LOG4SH_ERROR_} "'logger_addAppender(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
log4sh_appender_=$1
log4sh_logger_=${2:-${__LOG4SH_LOGGER_ROOT}}
( _logger_isValid "${log4sh_logger_}"; )
if [ $? -eq ${LOG4SH_TRUE} ]; then
log4sh_fqAppender_="${log4sh_logger_}.${log4sh_appender_}"
( _appender_isValid "${log4sh_fqAppender_}"; )
if [ $? -eq ${LOG4SH_FALSE} ]; then
# appender doesn't exist; add it
_log4sh_listAppend "__log4sh_logger_${log4sh_logger_}" \
"${log4sh_appender_}"
appender_setType ${log4sh_fqAppender_} ConsoleAppender
log4sh_return=${LOG4SH_TRUE}
else
${_LOG4SH_ERROR_} "'appender already exists (${log4sh_fqAppender_})'"
log4sh_return=${LOG4SH_FALSE}
fi
else
${_LOG4SH_ERROR_} "'invalid logger (${log4sh_logger_})'"
log4sh_return=${LOG4SH_FALSE}
fi
unset log4sh_appender_ log4sh_fqAppender_ log4sh_logger_
return ${log4sh_return}
}
# Retrieves the list of appenders from appropriate variable.
#
# Args:
# logger: string: name of logger
# Output:
# string: space separated list of appender names
# Returns:
# integer: undefined
_logger_getAppenders()
{
_log4sh_strToEval_="echo \"\${__log4sh_logger_${log4sh_logger_}}\""
eval "${_log4sh_strToEval_}"
unset _log4sh_strToEval_
}
# Gets the list of appenders for a logger.
#
# Args:
# logger: string: name of logger (optional)
# Output:
# string: space separated list of appender names
# Returns:
# integer: success of operation
logger_getAppenders()
{
if [ $# -gt 1 ]; then
${_LOG4SH_ERROR_} "'logger_getAppenders(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
log4sh_logger_=${1:-${__LOG4SH_LOGGER_ROOT}}
log4sh_return=${LOG4SH_FALSE}
( _logger_isValid "${log4sh_logger_}"; )
if [ $? -eq ${LOG4SH_TRUE} ]; then
_logger_getAppenders ${log4sh_logger_}
log4sh_return=${LOG4SH_TRUE}
fi
unset log4sh_logger_
return ${log4sh_return}
}
# Helper function to send an INFO priority message to the root logger.
#
# Args:
# msg: string: message to log
logger_info()
{
log ${__LOG4SH_LEVEL_INFO} "$@"
}
# The base logging function that sends a message to all appenders of a logger.
#
# Args:
# priority: string: the logging priority to limit message at
# STDIN|msg: string[]: the message to log
log()
{
if [ $# -ge 1 ]; then
${_LOG4SH_ERROR_} "'log(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
log4sh_priority_=$1
shift
[ $# -ne 0 ] && log4sh_msg_=$@ || log4sh_msg_=`cat`
# determine logger
[ -z "${log4sh_logger__}" ] \
&& log4sh_logger_=${__LOG4SH_LOGGER_ROOT} \
|| log4sh_logger_=${log4sh_logger__}
unset log4sh_msg_ log4sh_priority_
}
#------------------------------------------------------------------------------
# appender functions
#
# Determine if named appender is valid.
#
# Note: This function should always be called inside a subshell like (...;) due
# to variable scoping.
#
# Args:
# appender: string: name of [logger.]appender
# Returns:
# boolean: validity of logger
_appender_isValid()
{
${_LOG4SH_SPLIT_LOGGER_APPENDER_}
_log4sh_isValid_=${LOG4SH_FALSE}
( _logger_isValid "${log4sh_logger_}"; )
if [ $? -eq ${LOG4SH_TRUE} ]; then
_log4sh_appenders_=`_logger_getAppenders ${log4sh_logger_}`
for _log4sh_validAppender_ in ${_log4sh_appenders_}; do
${_LOG4SH_DEBUG_} "_log4sh_validAppender_=${_log4sh_validAppender_}"
if [ "${log4sh_appender_}" = "${_log4sh_validAppender_}" ]; then
_log4sh_isValid_=${LOG4SH_TRUE}
break
fi
done
fi
log4sh_return=${_log4sh_isValid_}
unset _log4sh_appenders_ _log4sh_isValid_ _log4sh_validAppender_
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${log4sh_return}
}
# Determine if appender type is valid.
#
# Note: if this function is called from a private function, it must be done
# inside a subshell like (...;) due to variable scoping.
#
# Args:
# type: string: appender type
# Returns:
# boolean: validity of appender type
_appender_isValidType()
{
_log4sh_type_=$1
_log4sh_isValid_=${LOG4SH_FALSE}
for _log4sh_validType_ in ${__log4sh_appenders}; do
if [ "${_log4sh_type_}" = "${_log4sh_validType_}" ]; then
_log4sh_isValid_=${LOG4SH_TRUE}
break
fi
done
log4sh_return=${_log4sh_isValid_}
unset _log4sh_isValid_ _log4sh_type_ _log4sh_validType_
return ${log4sh_return}
}
# Get the appender type for an appender.
#
# Args:
# appender: string: name of the [logger.]appender
# Outputs:
# string: appender type
# Returns:
# integer: success of the operation
appender_getType()
{
if [ $# -ne 1 ]; then
${_LOG4SH_ERROR_} "'appender_getType(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
${_LOG4SH_SPLIT_LOGGER_APPENDER_}
( _appender_isValid "${log4sh_fqAppender_}"; ) # subshell required
if [ $? -ne ${LOG4SH_TRUE} ]; then
${_LOG4SH_ERROR_} "'invalid appender (${log4sh_fqAppender_})'"
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${LOG4SH_FALSE}
fi
_log4sh_getValue "${log4sh_fqAppender_}.${__LOG4SH_KV_TYPE}"
log4sh_return=$?
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${log4sh_return}
}
# Set the appender type for an appender.
#
# Args:
# fqAppender: string: name of [logger.]appender
# type: string: appender type
# Returns:
# integer: success of the operation
appender_setType()
{
if [ $# -ne 2 ]; then
${_LOG4SH_ERROR_} "'appender_setType(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
${_LOG4SH_SPLIT_LOGGER_APPENDER_}
log4sh_type_=$1
( _appender_isValid "${log4sh_fqAppender_}"; )
if [ $? -ne ${LOG4SH_TRUE} ]; then
${_LOG4SH_ERROR_} "'invalid appender (${log4sh_fqAppender_})'"
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${LOG4SH_FALSE}
fi
( _appender_isValidType "${log4sh_type_}"; )
if [ $? -ne ${LOG4SH_TRUE} ]; then
${_LOG4SH_ERROR_} "'invalid appender type (${log4sh_type_})'"
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${LOG4SH_FALSE}
fi
# if type valid, instantiate new appender
log4sh_return=${LOG4SH_FALSE}
while true; do # while instead of if/then so we can end early
_appender_new_${log4sh_type_} ${log4sh_fqAppender_} || break
_log4sh_setValue "${log4sh_fqAppender_}.${__LOG4SH_KV_TYPE}" ${log4sh_type_}
log4sh_return=${LOG4SH_TRUE}
break
done
unset log4sh_type_
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${log4sh_return}
}
# Activate the options for an appender.
#
# Args:
# appender: string: name of [logger.]appender
appender_activateOptions()
{
${_LOG4SH_SPLIT_LOGGER_APPENDER_}
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
}
#-----------------------------------------------------------------------------
# main() code.
#
[ -z "${LOG4SH_DEBUG:-}" ] && _LOG4SH_DEBUG_=':' # disable debugging
__log4sh_tmpDir=`_log4sh_mktempDir`
__log4sh_dictFile="${__log4sh_tmpDir}/dictionary"
__log4sh_trapsFile="${__log4sh_tmpDir}/traps"
touch "${__log4sh_dictFile}" # prepare empty dictionary
trap >"${__log4sh_trapsFile}" # preserve old trap(s)
# configure traps
${_LOG4SH_DEBUG_} 'setting traps'
trap '_log4sh_cleanup EXIT' 0
trap '_log4sh_cleanup INT' 2
trap '_log4sh_cleanup TERM' 15
# setup default configuration
log4sh_resetConfiguration
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Shell
1
https://gitee.com/mirrors/log4sh.git
[email protected]:mirrors/log4sh.git
mirrors
log4sh
log4sh
master

搜索帮助