-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlisk-globals-lib.sh
294 lines (255 loc) · 8.1 KB
/
lisk-globals-lib.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#!/bin/bash
# lisk-globals-lib.sh: LISK 通用 shell 函数库
# 引入全局变量
# shellcheck disable=SC1090,SC1091
. "$(dirname "${BASH_SOURCE[0]}")/lisk-globals-env.sh"
# 日志记录函数
# 使用方法: LISK_log_info "This is an informational message."
# LISK_log_warn "This is a warning message."
# LISK_log_error "This is an error message."
# LISK_log_debug "This is a debug message." (仅当 LISK_LOG_LEVEL=DEBUG 时输出)
LISK_log_info() {
echo "$(date '+%Y-%m-%d %H:%M:%S') INFO: $1" >> "$LISK_LOG_FILE"
}
LISK_log_warn() {
echo "$(date '+%Y-%m-%d %H:%M:%S') WARN: $1" | tee -a "$LISK_LOG_FILE" >&2
}
LISK_log_error() {
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: $1" | tee -a "$LISK_LOG_FILE" >&2
}
LISK_log_debug() {
if [ "$LISK_LOG_LEVEL" = "DEBUG" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') DEBUG: $1" | tee -a "$LISK_LOG_FILE" >&2
fi
}
# 错误处理函数
# 使用方法: LISK_check_error "Error message" [exit_code]
LISK_check_error() {
local error_message="$1"
local exit_code="${2:-1}" # 默认退出代码为 1
if [ $? -ne 0 ]; then
LISK_log_error "$error_message (Script: ${BASH_SOURCE[0]}, Line: $LINENO)"
exit "$exit_code"
fi
}
# 执行命令并检查返回值
# 使用方法: LISK_run_command "command" "Error message if command fails"
LISK_run_command() {
local command="$1"
local error_message="$2"
"$command"
LISK_check_error "$error_message"
}
# 检查依赖项是否安装
# 使用方法: LISK_check_dependency "command" "Error message if command is not found"
LISK_check_dependency() {
local command_name="$1"
local error_message="$2"
if ! command -v "$command_name" &> /dev/null; then
LISK_log_error "$error_message"
exit 1
fi
}
# 下载文件 (支持重试、校验)
# 使用方法: LISK_download_file "URL" "Local file path" [checksum_type] [checksum_value]
LISK_download_file() {
local url="$1"
local local_path="$2"
local checksum_type="$3"
local checksum_value="$4"
local downloader="$LISK_DEFAULT_DOWNLOADER"
local retries="$LISK_MAX_RETRIES"
local temp_file
temp_file=$(mktemp -p "$LISK_TEMP_DIR" "lisk_download_XXXXXX") || {
LISK_log_error "Failed to create temporary file."
return 1
}
while [ $retries -gt 0 ]; do
case "$downloader" in
curl)
curl -s -# -m "$LISK_DOWNLOAD_TIMEOUT" -L "$url" -o "$temp_file"
;;
wget)
wget -q --progress=bar:force -T "$LISK_DOWNLOAD_TIMEOUT" -O "$temp_file" "$url"
;;
aria2c)
aria2c --quiet=true --timeout="$LISK_DOWNLOAD_TIMEOUT" --max-tries=1 --dir="$(dirname "$temp_file")" --out="$(basename "$temp_file")" "$url"
;;
*)
LISK_log_error "Unsupported downloader: $downloader"
rm -f "$temp_file"
return 1
;;
esac
if [ $? -eq 0 ]; then # 下载成功
if [ -n "$checksum_type" ] && [ -n "$checksum_value" ]; then
# 校验文件
case "$checksum_type" in
md5)
actual_checksum=$(md5sum "$temp_file" | awk '{print $1}')
;;
sha1)
actual_checksum=$(sha1sum "$temp_file" | awk '{print $1}')
;;
sha256)
actual_checksum=$(sha256sum "$temp_file" | awk '{print $1}')
;;
*)
LISK_log_error "Unsupported checksum type: $checksum_type"
rm -f "$temp_file"
return 1
;;
esac
if [ "$actual_checksum" != "$checksum_value" ]; then
LISK_log_error "Checksum mismatch for downloaded file: $local_path"
rm -f "$temp_file"
else
# 校验成功
mv "$temp_file" "$local_path"
return 0 # 成功返回
fi
else
# 不需要校验
mv "$temp_file" "$local_path"
return 0 # 成功返回
fi
fi
retries=$((retries - 1))
LISK_log_warn "Download failed, retrying ($retries retries remaining)..."
sleep 1 # 等待 1 秒再重试
done
LISK_log_error "Failed to download file after multiple retries: $url"
rm -f "$temp_file"
return 1
}
# 安装软件包 (支持多种 Linux 发行版)
LISK_install_packages() {
local packages="$1"
local install_cmd=""
case "$LISK_DISTRO_FAMILY" in
Debian)
install_cmd="apt update && apt install -y"
;;
RHEL)
install_cmd="dnf install -y"
;;
SUSE)
install_cmd="zypper install -y"
;;
Alpine)
install_cmd="apk add"
;;
Arch)
install_cmd="pacman -Syu --noconfirm"
;;
*)
LISK_log_error "Unsupported distribution family: $LISK_DISTRO_FAMILY"
return 1
;;
esac
if [ -z "$install_cmd" ]; then
LISK_log_error "No package installation command defined for distribution family: $LISK_DISTRO_FAMILY"
return 1
fi
if [ -z "$packages" ] ;then
return 0
fi
# 使用 sudo 执行安装命令,所有操作必须以 root 权限执行。
sudo $install_cmd $packages
}
# 卸载软件包 (支持多种 Linux 发行版)
# Usage: LISK_uninstall_packages "package1 package2 ..."
LISK_uninstall_packages() {
local packages="$1"
local uninstall_cmd=""
case "$LISK_DISTRO_FAMILY" in
Debian)
uninstall_cmd="apt remove -y"
;;
RHEL)
uninstall_cmd="dnf remove -y"
;;
SUSE)
uninstall_cmd="zypper remove -y"
;;
Alpine)
uninstall_cmd="apk del"
;;
Arch)
uninstall_cmd="pacman -R --noconfirm"
;;
*)
LISK_log_error "Unsupported distribution family: $LISK_DISTRO_FAMILY"
return 1
;;
esac
if [ -z "$uninstall_cmd" ]; then
LISK_log_error "No package uninstallation command defined for distribution family: $LISK_DISTRO_FAMILY"
return 1
fi
if [ -z "$packages" ]; then
return 0 # 没有要卸载的软件包,直接返回成功
fi
# 使用 sudo 执行卸载命令
sudo $uninstall_cmd $packages
}
# 显示进度条
LISK_show_progress() {
local current="$1"
local total="$2"
local bar_width="${3:-50}"
local percentage=$((current * 100 / total))
local filled_width=$((current * bar_width / total))
local empty_width=$((bar_width - filled_width))
# 构建进度条字符串
local bar="["
printf -v filled_part '%*s' "$filled_width" ''
bar+="${filled_part// /#}"
printf -v empty_part '%*s' "$empty_width" ''
bar+="${empty_part// /=}"
bar+="]"
printf "\r%s %3d%%" "$bar" "$percentage"
# 如果完成,打印换行符
if [ "$current" -eq "$total" ]; then
echo
fi
}
# 确认操作
LISK_confirm() {
local prompt="$1"
local default="${2:-n}" # 默认答案为 "n" (no)
while true; do
read -r -p "$prompt (y/n) [default: $default]: " response
case "$response" in
[Yy]*) return 0 ;; # 返回 0 表示确认
[Nn]*) return 1 ;; # 返回 1 表示取消
"")
if [[ "$default" == [Yy] ]]; then
return 0
else
return 1
fi
;;
*) echo "Invalid input. Please enter 'y' or 'n'." ;;
esac
done
}
# 字符串替换
LISK_string_replace() {
local string="$1"
local old="$2"
local new="$3"
echo "${string//$old/$new}"
}
# 检查数组是否包含某个元素
LISK_array_contains() {
local array_name="$1"
local search_term="$2"
local element
for element in "${!array_name[@]}"; do
if [[ "$element" == "$search_term" ]]; then
return 0 # 找到,返回 0
fi
done
return 1 # 未找到,返回 1
}