代码拉取完成,页面将自动刷新
#!/bin/bash
# 加载此文件, 会自动加载所有的函数. 同时用这个变量标记, 避免重复加载
export BASE_FUNC_DEF=1
# 检查当前系统类型.
# 返回: mac, linux, windows
#
system_type() {
if [[ "$(uname)" == "Darwin" ]]; then
# Mac OS X 操作系统
echo 'mac'
elif [[ "$(expr substr "$(uname -s)" 1 5)" == "Linux" ]]; then
# GNU/Linux操作系统
echo "linux"
elif [[ "$(expr substr "$(uname -s)" 1 10)" == "MINGW32_NT" ]]; then
# Windows NT操作系统
echo 'windows'
fi
}
# 生成随机字符串
#
_uuid() {
uuidgen | sed 's/-//g' | tr '[:upper:]' '[:lower:]'
}
# 随机数生成函数.
# 参数:
# $1: min 最小值(包含)
# $2: max 最大值(包含)
# 示例: random 1 100
# 返回: 1~100之间的随机数
_rand() {
local min max num
min=$1
max=$(($2 - $min + 1))
num=$(($RANDOM + 1000000000)) #增加一个10位的数再求余
echo $(($num % $max + $min))
}
# ---------------------------------------------- 日期时间工具类 --------------------------------------------------------
# 输出当前时间戳,10位 , 不包含ms
timestamp() {
date +%s
}
# 输出当前时间戳,13位 , 包含ms
# 注意: 由于 Mac OS X 操作系统不支持毫秒级时间戳, 所以这里直接补000
# 调用示例:
# ms=`timestamp_ms`
timestamp_ms() {
if [[ "$(system_type)" == linux ]]; then
date +%s%3N
return
fi
# Mac OS X 操作系统, 只能精确到秒. 直接补000
if [[ "$(system_type)" == mac ]]; then
date +%s000
return
fi
echo "不支持的操作系统类型: $(system_type)"
exit 1
}
# 当前时间戳转换为日期
timestamp_date() {
date +"%Y-%m-%d %H:%M:%S"
}
# 当前时间: %Y-%m-%d %H:%M:%S
now() {
timestamp_date
}
# 时间戳格式化.
# 参数:
# $1: timestamp 时间戳 (秒,如果是毫秒需要截取前10位)
# $2: fmt 格式化字符串, 例如: %Y-%m-%d %H:%M:%S , %Y%m%d%H%M%S ,
# 具体格式定义可以参考: https://www.ltsplus.com/linux/linux-date-format-shell-script
# 重要格式说明:
# %s: 时间戳 (10位)
# %Y: 年份 示例: 2013
# %m: 月份 示例: 07
# %d: day of month (e.g, 01) 示例: 01
# %H: hour(00..23) 示例: 23
# %M: minute (00..59) 示例: 59
# %S: 秒
# %N nanoseconds (000000000..999999999)
# 输出: 格式化后的日期
# 示例: timestamp_format 1666766635 "%Y-%m-%d %H:%M:%S"
timestamp_format() {
local timestamp="$1"
local fmt="$2"
local formatted_date
# 1666766635000
if [ "${#timestamp}" -gt 10 ]; then
timestamp=${timestamp:0:10}
fi
case "$(system_type)" in
'linux')
formatted_date=$(date -d "@${timestamp}" +\""${fmt}"\")
;;
'mac')
#
# Mac OS X 操作系统, 另外一种实现.
# date -jf "%s" "${timestamp}" +"%Y-%m-%d %H:%M:%S"
# -j: 不设置系统时间
# -f: 使用指定格式解析时间
# %s: 时间戳
# %Y: 年份
# %m: 月份
# %d: 日期
# %H: 小时
# %M: 分钟
# %S: 秒
# 参数说明:
# -r: 显示指定时间戳
formatted_date=$(date -r "${timestamp}" +"${fmt}")
;;
*)
echo "不支持的操作系统类型: $(system_type)"
exit 1
;;
esac
echo "$formatted_date"
}
# 时间戳转日期: %Y%m%d%H%M%S
timestamp_to_yyyyMMddHHmmss() {
timestamp_format "$1" "%Y%m%d%H%M%S"
}
# 时间戳转日期: %Y-%m-%d %H:%M:%S
# $1: 时间戳 (秒,如果是毫秒需要截取前10位)
# 示例: timestamp_to_date 1666766635
# 输出: 2022-10-26 14:43:55
#
timestamp_to_date() {
timestamp_format "$1" "%Y-%m-%d %H:%M:%S"
}
# 功能: 把 yyyy-MM-dd HH:mm:ss 转换为时间戳
# 示例: timestamp_from_date '2024-01-01 00:00:00'
timestamp_from_date() {
local date="$1"
local timestamp
case "$(system_type)" in
'linux')
timestamp=$(date -d "${date}" +%s)
;;
'mac')
timestamp=$(date -j -f "%Y-%m-%d %H:%M:%S" "${date}" +%s)
;;
*)
echo "不支持的操作系统类型: $(system_type)"
exit 1
;;
esac
echo "$timestamp"
}
# ---------------------------------------------- 字符串工具类 --------------------------------------------------------
# trim input string $1
# 功能说明
# 参数说明
# $1: 待处理的字符串
# 返回值: trim后的字符串
## ============================================================================
trim() {
echo "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}
# 函数:trim
# shellcheck disable=SC2001
func_trim() {
echo "$1" | sed 's;^[ ]*\(.*[^ ]\)[ ]*$;\1;'
}
# 工具函数: 把字符串中的以空格分割的字符串重新分割为多行. 例如: "a b c" => "a\nb\nc"
# 参数列表:
# $1: inputString 输入字符串
# $2: splitter 分割符, 默认为空格
strings_line_to_multiline() {
local splitter=' '
if [ -n "$2" ]; then
splitter="$2"
fi
local multi_lines="${1//${splitter}/$'\n'}"
echo "${multi_lines}"
}
# 工具函数: 把字符串中的以多行分割的字符串重新分割为一行. 例如: "a\nb\nc" => "a b c"
# 参数列表:
# $1: inputString 输入字符串
# 输出: 一行字符串
strings_multiline_to_line() {
local single_line="${1//$'\n'/ }"
echo "${single_line}"
}
# 获取文件名后缀(包含点号), 并且转换为小写, 如果没有后缀,则返回空字符串
# $1: file_name
# 示例: func_get_file_name_suffix "test.txt"
# 输出: .txt
func_get_file_name_suffix() {
local file_name="$1"
# if file_name do not contain '.' ; return empty string
if [[ "${file_name}" =~ .*\.[0-9A-Za-z]+ ]]; then
# 从$string开头删除最长匹配$substr子串 ${string##substr} , 并且转换为小写
echo ".${file_name##*.}" | tr '[:upper:]' '[:lower:]'
return
fi
echo ""
}
# 获取文件名后缀(不含点号), 并且转换为小写, 如果没有后缀,则返回空字符串
# $1: file_name
# 示例: func_get_file_name_suffix "test.txt"
# 输出: txt
func_get_file_name_suffix_without_dot() {
local file_name="$1"
# if file_name do not contain '.' ; return empty string
if [[ "${file_name}" =~ .*\.[0-9A-Za-z]+ ]]; then
# 从$string开头删除最长匹配$substr子串 ${string##substr} , 并且转换为小写
echo "${file_name##*.}" | tr '[:upper:]' '[:lower:]'
return
fi
echo ""
}
# ------------------------------------------------ JSON 工具类 --------------------------------------------------------
# 判断是否是有效的json字符串
func_is_valid_json() {
if jq -e . >/dev/null 2>&1 <<<"$1"; then
return 0
else
return 1
fi
}
# 读取jsonParam的key对应的值. 如果key不存在,则返回空null (不是空字符串)
# $1 json
# $2 key
# 示例: JSON_PARAM_STRING '{"key":"value"}' '.key'
# 返回: value
JSON_PARAM_STRING() {
local key="$2"
# 对key进行处理,如果不是以.开头,则加上.
if [[ ! "$key" =~ \..* ]]; then
key=".$key"
fi
echo "$1" | jq -r "$key"
}
# 读取jsonParam的key对应的值. 如果key不存在,则返回空String
# $1 json
# $2 key
JSON_PARAM_STRING_TRIM2EMPTY() {
local value
local key="$2"
# 对key进行处理,如果不是以.开头,则加上.
if [[ ! "$key" =~ \..* ]]; then
key=".$key"
fi
value=$(echo "$1" | jq -r "$key")
if [[ ${value} == null ]]; then
echo ""
exit 0
fi
echo "$value"
}
# 读取jsonParam中的key对应的值. 如果key不存在,则返回空 null
# 注意:
# 1) 如果key的值为string,实际会返回: "StringValue"
# 2) 如果是对象,返回的是json字符串
JSON_PARAM_OBJ() {
local key="$2"
# 对key进行处理,如果不是以.开头,则加上.
if [[ ! "$key" =~ \..* ]]; then
key=".$key"
fi
echo "$1" | jq "$key"
}
# JSON数据构建器. 可以像构建MAP一样构建JSON对象
# 示例:
# JSON_BUILDER key1 val1 key2 '{"key":"value"}'
#
# https://unix.stackexchange.com/questions/686785/unix-shell-quoting-issues-error-in-jq-command
# https://stackoverflow.com/questions/70617932/bash-script-to-add-a-new-key-value-pair-dynamically-in-json
JSON_BUILDER() {
local json='{}'
for ((cnt = 0; cnt < $#; cnt = cnt + 2)); do
#echo "key=${*:cnt+1:1}, value=${*:cnt+2:1}"
local key="${*:cnt+1:1}"
local val="${*:cnt+2:1}"
# if [[ "${val}" =~ ^[0-9]+(.[0-9]+){0,1}$ ]] || [[ "$val" == "true" ]] || [[ "$val" =~ ^\{.*\}$ ]]; then
# 去除数字. 只把对象和bool值添加到json中
if [[ "$val" == "true" ]] || [[ "$val" =~ ^\{.*\}$ ]]; then
# 场景: bool值 , 数字 , 对象 时, 直接添加
json=$(echo "$json" | jq '. += { '"\"${key}\""' : '"${val}"'}')
else
# value是一个string的情况下,要双引号
json=$(echo "$json" | jq '. += { '"\"${key}\""' : '"\"${val}\""'}')
fi
done
#cat <<< $(jq '.student1 += { "Phone'"${m}"'" : '"${i}"'}' Students.json) > Students.json
echo "${json}"
}
# REST_API 返回数据格式定义
# 格式示例:
# {
# "ret": true
# }
# 参数:
# $1 - ret (true|false) 必须
# $2 - errcode 可选
# $3 - errmsg 可选
# $4 - data - jsonObject json对象 可选
# 一个参数: API_RESPONSE_RETURN true
# 两个参数: API_RESPONSE_RETURN true jsonData
# 两个参数: API_RESPONSE_RETURN false msg
# 两个参数: API_RESPONSE_RETURN false code
API_RESPONSE_RETURN() {
local ret=true
local errcode=0
local errmsg=""
local data=null
case $# in
1)
ret=${1}
;;
2)
ret="$1"
# echo "================"
# echo "$2" | od -c
# echo "================"
# 两个参数:
# 第二个参数可能是 code / msg / data
# 左边的参数 $2 必须加双引号
if [[ "$2" =~ ^[-]{0,1}[0-9]+$ ]]; then
# errCode
errcode=$2
elif [[ "$2" =~ ^\{.*\}$ ]]; then
# data
data="$2"
else
errmsg="$2"
fi
;;
?)
ret=${1}
errcode="$2"
errmsg="$3"
if [[ "$4" =~ \{.*\} ]]; then
data="$4"
fi
;;
esac
if [ "$ret" = false ] && [ "$errcode" = 0 ]; then
errcode=-1
fi
# shellcheck disable=SC2155
local REST_API_JSON=$(jq -n \
--arg ret "${ret}" \
--argjson errcode "$errcode" \
--arg errmsg "$errmsg" \
--argjson data "$data" \
'
{
ret: $ret | test("true"),
errcode: $errcode ,
errmsg: $errmsg,
data: $data
}
')
echo "$REST_API_JSON"
}
# REST_API 调用接口, 并直接打印返回结果. 这个不适合在脚本中调用, 适合在命令行中调用 ( 未调试完成 )
# 参数:
# $1 - api_url
# $2 - api_method (GET/POST/PUT/DELETE)
# $3 - api_data
# $4 - api_header
# $5 - api_timeout
REST_API_CALL_AND_PRINT() {
local api_url="$1"
local api_method="${2:-GET}"
local api_data="$3"
local api_header="${4:-contentType: application/json}"
local api_timeout="${5:-60}"
lacal AUTH_HEADER="${6:-leo-fct-auth: 1691571163}"
local api_response
api_response=$(curl -s -X "${api_method}" -H "${api_header}" -d "${api_data}" --connect-timeout "${api_timeout}" "${api_url}" 2>/dev/null)
status=$(echo "${api_response}" | jq .status)
# 返回成功时, 只输出data字段
if [[ $status == 200 ]]; then
echo "${api_response}" | jq .data
else
echo "${api_response}" | jq .
fi
}
# ------------------------------------------------ debug log 工具类 ---------------------------------------------------
function git_location_info() {
local repoName="$(git config --get remote.origin.url | sed 's/.*\///g')"
local branch="$(git branch 2>/dev/null | grep '\*')"
echo "[${repoName}:${branch:-N/A}]"
}
#功能说明: 通用日志 输出函数
#参数说明:
# $1:level (error/warn/info/concern)
# $2:message
#使用方法:
# func_log_print "level" "message"
function func_log_print() {
local level="$1"
local msg="$2"
case $level in
error) printf "\033[41;30;1m${msg}\033[0m\n" ;;
warn) printf "\033[43;30;1m${msg}\033[0m\n" ;;
info) printf "\033[47;30;1m${msg}\033[0m\n" ;;
concern) printf "\033[42;30;1m${msg}\033[0m\n" ;;
*) echo "${msg}" ;;
esac
}
#功能说明: 返回当前函数信息输出格式
#参数说明: 无参数
#使用方法:
# func_info_pattern
##############################################################################
function func_info_pattern() {
local info_pattern=""
local depth=${#FUNCNAME[*]}
for ((i = 3; i < depth; i++)); do
info_pattern="$info_pattern@@${FUNCNAME[i]}:${BASH_LINENO[i - 1]}"
done
# get file name
# local file_depth=${#BASH_SOURCE[*]}
# for (( i = 0 ; i < file_depth ; i++ ))
# do
# echo "file[$i]: [${BASH_SOURCE[i]}], func:${FUNCNAME[i]} , BASH_LINENO:${BASH_LINENO[i]}" >&2
# done
#
# echo "file_len: ${#BASH_SOURCE[*]},func_len: ${#FUNCNAME[*]}" >&2
local FILE_NAME="${BASH_SOURCE[2]##*/}"
# 日志格式: [函数名(文件名:行号)] [git仓库名:分支名] [日志内容]
echo "${FUNCNAME[2]}(${FILE_NAME}:${BASH_LINENO[1]})$info_pattern"
}
# 功能说明: INFO 日志输出函数
echo_info() {
local info_pattern=$(func_info_pattern)
#func_log_print "info" "[+] $(date +'%Y-%m-%d %H:%M:%S') [INFO ][$info_pattern] $(git_location_info): $*" 1>&2
printf "\033[32;40;1m[+] $(date +'%Y-%m-%d %H:%M:%S') [INFO ][$info_pattern] $(git_location_info)\033[0m: $*\n" 1>&2
}
echo_error() {
local info_pattern=$(func_info_pattern)
func_log_print "error" "[+] $(date +'%Y-%m-%d %H:%M:%S') [ERROR ][$info_pattern] $(git_location_info): $*" 1>&2
}
# 对于debug函数的输出.只有程序运行在debug级别的时候.才输出
echo_debug() {
# "\033[43;30;1m${msg}\033[0m"
if [[ -z "${debug}" ]]; then
return
fi
# 日志格式: [日期时间] [日志级别] [函数名(文件名:行号)] [git仓库名:分支名] [日志内容]
local info_pattern=$(func_info_pattern)
# printf "\033[32;40;1m[+] $(date +'%Y-%m-%d %H:%M:%S') [DEBUG ][$info_pattern] $(git_location_info)\033[0m: $*\n" 1>&2
printf "\033[47;30;1m[+] $(date +'%Y-%m-%d %H:%M:%S') [DEBUG ][$info_pattern] $(git_location_info)\033[0m: $*\n" 1>&2
}
echo_concern() {
local info_pattern=$(func_info_pattern)
func_log_print "concern" "[+] $(date +'%Y-%m-%d %H:%M:%S') [CONCERN][$info_pattern] $(git_location_info): $*" 1>&2
}
echo_warn() {
local info_pattern=$(func_info_pattern)
printf "\033[32;40;1m[+] $(date +'%Y-%m-%d %H:%M:%S') [WARN ][$info_pattern] $(git_location_info)\033[0m: \033[43;30;1m$*\033[0m\n" 1>&2
#func_log_print "warn" "[+] `date +'%H:%M:%S'` warn($info_pattern@$LINENO) `git_location_info`: $@" 1>&2;
}
echo_warn_detail() {
local info_pattern=$(func_info_pattern)
func_log_print "warn" "[+] $(date +'%Y-%m-%d %H:%M:%S') [WARN ][$info_pattern] $(git_location_info): $*" 1>&2
}
# ------------------------------------------------ 函数调用参数工具类 ---------------------------------------------------
_param_show_help(){
if [[ $# -eq 0 ]] || [[ $1 == "-h" ]] || [[ $1 == '--help' ]] ; then
echo yes
return
fi
echo no
}
# 判定参数是否存在
# $1: 待检查的参数名
# $2: 参数列表
_param_exist(){
local to_checked_param="$1"
shift
while [[ $# -gt 0 ]];
do
if [[ "$1" == "$to_checked_param" ]]; then
echo "yes"
return 0
fi
shift
done
echo "no"
return 1
}
# 获取参数. 兼容短参数与长参数传递形式. 例如: --file="test.txt" 或者 -f "test.txt"
# 判定逻辑, 优先使用长参数, 如果长参数不存在, 则使用短参数. 如果短参数也不存在, 则返回空字符串
# 可以同时传入短参和长参. 短参和长参的优先级, 以传入的参数顺序为准, 参数名用 | 分隔, 例如: -f|--file
# 调用示例:
# param=$(_param_parse "--paramName" "$@")
# param=$(_param_parse "-p" "$@")
# param=$(_param_parse "-p|--paramName" "$@")
_param_parse() {
# >&2 echo "param_parse: $*"
local target_arg_name="$1"
shift 1
local target_arg_name1="${target_arg_name%%|*}" # 删除最长的 匹配 |* 的后缀子串,剩下的就是参数名1
local target_arg_name2="${target_arg_name#*|}" # 删除最短的 匹配 *| 的前缀子串, 剩下的就是参数名2
local arg_name
local arg_value=""
# >&2 echo "param_parse: $*"
local _param
local _param_name
local _param_value
while [[ $# -gt 0 ]]; do
_param="$1"
_param_name="${_param%%=*}" # 删除最长的 匹配 =* 的后缀子串,剩下的就是参数名
_param_value=""
# 如果参数中包含 = , 则获取参数值
if [[ "$_param" =~ .*=.* ]]; then
_param_value="${_param#*=}" # 删除最短的 匹配 *= 的前缀子串, 剩下的就是参数值
fi
# echo "param_parse: _param_name: ${_param_name}, _param_value: '${_param_value}'"
# 参数名相同,发现目标参数, 且参数值为空 , 则获取下一个参数作为参数值
if [[ "$_param_name" != "$target_arg_name1" ]] && [[ "${_param_name}" != "${target_arg_name2}" ]]; then
shift 1
continue
fi
if [[ -z "${_param_value}" ]]; then
arg_name="$_param_name"
arg_value="$2"
shift 2
else
arg_name="$_param_name"
arg_value="$_param_value"
shift 1
fi
break
done
if [[ -z "${arg_value}" ]]; then
echo_debug "param '${target_arg_name}' not found"
fi
echo "${arg_value}"
}
# ------------------------------------------------ 环境设置.方便全局控制 ------------------------------------------------
if [[ $(_param_exist '-x' "$@") == yes ]]; then
export debug=1
fi
# 请转入 server_id
echo "请输入 server_id"
read server_id
server_id=$(func_trim "$server_id")
if [[ -z "$server_id" ]]; then
echo_warn "请输入有效的 server_id (这个 id 可以在你的 confluence 的管理页找到)"
exit 1
fi
echo "请输入 plugin id ,一般在插件后台为: com.xx.xxx 形式"
read plugin_id
plugin_id=$(func_trim "$plugin_id")
if [[ -z "$plugin_id" ]]; then
echo_warn "请输入有效的 plugin_id"
exit 1
fi
echo_debug "server_id:${server_id},plugin_id=${plugin_id}"
docker exec -it confluence-8.5.2 java -jar /opt/atlassian/confluence/atlassian-agent.jar -s "$server_id" -p "$plugin_id" -m test@test.com -n test -o test
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。