130 lines
3.5 KiB
Bash
130 lines
3.5 KiB
Bash
#!/bin/bash
|
|
# Ver: 1.1 by Endial Fang (endial@126.com)
|
|
#
|
|
# 文件管理函数库
|
|
|
|
# 加载依赖项
|
|
. /usr/local/scripts/liblog.sh # 日志输出函数库
|
|
|
|
# 函数列表
|
|
|
|
# 域名解析
|
|
# 参数:
|
|
# $1 - 需要解析的主机名
|
|
# $2 - IP 地址版本 v4/v6, 为空时解析所有版本
|
|
# 返回值:
|
|
# IP地址
|
|
dns_lookup() {
|
|
local host="${1:?host is missing}"
|
|
local ip_version="${2:-}"
|
|
|
|
getent "ahosts${ip_version}" "$host" | awk '/STREAM/ {print $1 }' | head -n 1
|
|
}
|
|
|
|
# 尝试解析域名并返回对应的 IP
|
|
# 参数:
|
|
# $1 - 主机名
|
|
# $2 - 尝试次数
|
|
# $3 - 重试间隔时间(秒)
|
|
# 返回值:
|
|
# IP地址
|
|
wait_for_dns_lookup() {
|
|
local hostname="${1:?hostname is missing}"
|
|
local retries="${2:-5}"
|
|
local seconds="${3:-1}"
|
|
check_host() {
|
|
if [[ $(dns_lookup "$hostname") == "" ]]; then
|
|
false
|
|
else
|
|
true
|
|
fi
|
|
}
|
|
# Wait for the host to be ready
|
|
retry_while "check_host ${hostname}" "$retries" "$seconds"
|
|
dns_lookup "$hostname"
|
|
}
|
|
|
|
# 获取当前主机 IP
|
|
# 返回值:
|
|
# IP地址
|
|
get_machine_ip() {
|
|
local -a ip_addresses
|
|
local hostname
|
|
hostname="$(hostname)"
|
|
read -r -a ip_addresses <<< "$(dns_lookup "$hostname" | xargs echo)"
|
|
if [[ "${#ip_addresses[@]}" -gt 1 ]]; then
|
|
LOG_W "Found more than one IP address associated to hostname ${hostname}: ${ip_addresses[*]}, will use ${ip_addresses[0]}"
|
|
elif [[ "${#ip_addresses[@]}" -lt 1 ]]; then
|
|
LOG_E "Could not find any IP address associated to hostname ${hostname}"
|
|
exit 1
|
|
fi
|
|
echo "${ip_addresses[0]}"
|
|
}
|
|
|
|
# 检测指定的主机名是否可解析
|
|
# 参数:
|
|
# $1 - 待检测的主机名
|
|
# 返回值:
|
|
# true / false
|
|
is_hostname_resolved() {
|
|
local -r host="${1:?missing value}"
|
|
if [[ -n "$(dns_lookup "$host")" ]]; then
|
|
true
|
|
else
|
|
false
|
|
fi
|
|
}
|
|
|
|
# 解析 URL
|
|
# 参数:
|
|
# $1 - URI 字符串
|
|
# $2 - 类型字符串. 有效值 (scheme, authority, userinfo, host, port, path, query or fragment)
|
|
# 返回值:
|
|
# 字符串
|
|
parse_uri() {
|
|
local uri="${1:?uri is missing}"
|
|
local component="${2:?component is missing}"
|
|
|
|
# Solution based on https://tools.ietf.org/html/rfc3986#appendix-B with
|
|
# additional sub-expressions to split authority into userinfo, host and port
|
|
# Credits to Patryk Obara (see https://stackoverflow.com/a/45977232/6694969)
|
|
local -r URI_REGEX='^(([^:/?#]+):)?(//((([^@/?#]+)@)?([^:/?#]+)(:([0-9]+))?))?(/([^?#]*))?(\?([^#]*))?(#(.*))?'
|
|
# || | ||| | | | | | | | | |
|
|
# |2 scheme | ||6 userinfo 7 host | 9 port | 11 rpath | 13 query | 15 fragment
|
|
# 1 scheme: | |5 userinfo@ 8 :... 10 path 12 ?... 14 #...
|
|
# | 4 authority
|
|
# 3 //...
|
|
local index=0
|
|
case "$component" in
|
|
scheme)
|
|
index=2
|
|
;;
|
|
authority)
|
|
index=4
|
|
;;
|
|
userinfo)
|
|
index=6
|
|
;;
|
|
host)
|
|
index=7
|
|
;;
|
|
port)
|
|
index=9
|
|
;;
|
|
path)
|
|
index=10
|
|
;;
|
|
query)
|
|
index=13
|
|
;;
|
|
fragment)
|
|
index=14
|
|
;;
|
|
*)
|
|
stderr_print "unrecognized component $component"
|
|
return 1
|
|
;;
|
|
esac
|
|
[[ "$uri" =~ $URI_REGEX ]] && echo "${BASH_REMATCH[${index}]}"
|
|
}
|