-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathposix
More file actions
421 lines (350 loc) · 11 KB
/
posix
File metadata and controls
421 lines (350 loc) · 11 KB
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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
#!/usr/bin/env bash
# ---------------------------------------------------------------
# File Name : installer.sh
# File Authors : GnixAij <gaojiaxing0220@gmail.com>
# | xuan <wick.dynex@qq.com>
# | ChatGPT <https://chatgpt.com>
# | Aoran Zeng <ccmywish@qq.com>
# Contributors : GitHub Copilot <https://github.com/copilot>
# | DeepSeek <https://chat.deepseek.com/>
# |
# Created On : <2024-10-25>
# Last Modified : <2025-07-12>
#
# chsrc installer for POSIX (mainly Linux & macOS)
# ---------------------------------------------------------------
binary_name="chsrc"
# 用户指定的安装目录,函数set_install_dir()将填充/校验该变量
userOpt_install_dir=""
# 默认安装目录
default_install_dir_4root="/usr/local/bin"
default_install_dir_4nonroot="$HOME/.local/bin"
# 若用户指定的目录不存在则会创建该目录
tmp_created_install_dir=""
userOpt_version="pre"
userOpt_help=0
userOpt_lang="zh"
info() {
echo "[INFO] $*"
}
warn() {
echo "[WARN] $*"
}
error() {
echo "[ERROR] $*"
}
# 用户自己输入
typeit() {
echo "[->] $ $*"
}
error_exit() {
echo -e "[ERROR] $*" >&2
exit 1
}
is_zh() {
if [ "$userOpt_lang" = "zh" ]; then
return 0
else
return 1
fi
}
help() {
if is_zh; then
echo "chsrc-installer: 在类Unix操作系统上安装 chsrc"
echo
echo "使用: install.sh [选项]"
echo "选项:"
echo "-h 打印此帮助信息"
echo "-d <dir> 指定安装目录,默认为 $default_install_dir_4root 或 $default_install_dir_4nonroot"
echo "-v <version> 指定 chsrc 版本"
echo "-l <lang> 指定输出语言,支持 zh 和 en "
echo
else
echo "chsrc-installer: Install chsrc on any Unix-like OS"
echo
echo "Usage: install.sh [options]"
echo "Options:"
echo "-h Print this help information"
echo "-d <dir> Specify installation directory, default is $default_install_dir_4root OR $default_install_dir_4nonroot"
echo "-v <version> Specify chsrc version"
echo "-l <lang> Specify output language, supports zh and en"
echo
fi
}
let_user_build() {
if command -v make &>/dev/null; then
# 检测是否是 GNU make,如果是则用 make,如果不是则用C编译器来编译
if make --version | grep -q "GNU Make"; then
typeit "make"
else
if is_zh; then
warn "检测到非 GNU make,本项目的Makefile仅支持GNU make"
else
warn "Non-GNU make was detected, the Makefile for this project only supports GNU make"
fi
typeit "cc/gcc/clang -Iinclude -Ilib src/chsrc-main.c -o chsrc"
fi
else
if is_zh; then
warn "未检测到GNU make,需手动执行编译命令:"
else
warn "GNU make was not detected, so we need to run the compile command manually:"
fi
typeit "cc/gcc/clang -Iinclude -Ilib src/chsrc-main.c -o chsrc"
fi
}
let_user_use_bootstrap() {
info "请参考: https://github.com/RubyMetric/chsrc/tree/main/bootstrap 查找是否存在已有的 boostrapper"
}
let_user_compile() {
source_zip_url="https://gitee.com/RubyMetric/chsrc/repository/archive/main.zip"
echo ""
if command -v git &>/dev/null; then
typeit "git clone https://gitee.com/RubyMetric/chsrc.git"
typeit "cd chsrc"
let_user_build
exit 1
elif command -v curl &>/dev/null; then
typeit "curl -LO $source_zip_url"
elif command -v wget &>/dev/null; then
typeit "wget $source_zip_url"
else
info "Please download the source code: $source_zip_url"
fi
typeit "unzip ./main.zip "
typeit "cd ./chsrc-main"
let_user_build
exit 1;
}
get_arch() {
echo $(uname -m | tr '[:upper:]' '[:lower:]')
}
get_platform() {
echo $(uname -s | awk '{print tolower($0)}')
}
# Linux -> GNU/Linux
# Android -> Android
get_os() {
echo $(uname -o | awk '{print tolower($0)}')
}
set_arch() {
arch=$(get_arch)
case "$arch" in
x86_64) arch="x64" ;;
aarch64|arm64) arch="aarch64" ;;
riscv64) arch="riscv64" ;;
armv7*) arch="armv7" ;;
*)
if is_zh; then
warn "抱歉, 暂无预编译二进制文件供你所在的平台架构: ${arch} 使用。请使用 chsrc-bootstrap 或 自行编译:"
else
warn "Sorry, No precompiled binaries for your arch: ${arch}. Please compile it on your own:"
fi
let_user_use_bootstrap
let_user_compile
exit 1
;;
esac
}
set_platform() {
platform=$(get_platform)
case "$platform" in
linux)
platform="linux"
whatos=$(get_os)
if [ "$whatos" = "android" ]; then
if is_zh; then
info "使用 chsrc-bootstrap: Termux"
else
info "Use chsrc-bootstrap: Termux"
fi
wget -O - https://gitee.com/RubyMetric/chsrc/raw/main/bootstrap/Termux.bash | bash
exit 1
fi
;;
darwin) platform="macos" ;;
bsd|dragonfly)
platform="bsd"
if is_zh; then
info "抱歉, 暂无预编译二进制文件供BSD使用。请使用 chsrc-bootstrap 或 自行编译:"
else
info "Sorry, No precompiled binaries for BSD! Please compile it on your own:"
fi
let_user_use_bootstrap
let_user_compile
exit 1
;;
*)
if is_zh; then
error_exit "抱歉,暂无预编译二进制文件供你所在的平台: ${platform} 使用。请使用 chsrc-bootstrap 或 自行编译:"
else
error_exit "Sorry, No precompiled binaries for your platform: ${platform}. Please compile it on your own:"
fi
let_user_use_bootstrap
let_user_compile
exit 1
;;
esac
}
set_binary_version() {
if [[ ! "$userOpt_version" =~ ^(pre|0\.([1-9])\.([0-9]))$ ]]; then
# version 不符合条件,报错
if is_zh; then
error_exit "不支持的版本: ${userOpt_version},版本号必须为 0.x.y (>=0.1.4) 或 'pre'"
else
error_exit "Unsupported version: ${userOpt_version}. Version number must be 0.x.y (>=0.1.4) or 'pre'"
fi
fi
binary_version="${userOpt_version}"
# version 版本不是 'pre',添加'v'前缀
if [[ "$userOpt_version" =~ ^(0\.([1-9])\.([0-9]))$ ]]; then
binary_version="v${userOpt_version}"
fi
}
#
# 1. 若用户指定了安装目录,则安装至那里
#
# 若安装目录不存在,该脚本会为用户创建
#
# 2. 若用户没有指定安装目录:
#
# 2.1 若 chsrc 已存在,自动安装到该位置
# 2.2 若 chsrc 不存在,安装到两个预定义的默认安装位置
#
set_install_dir() {
if [ -n "$userOpt_install_dir" ]; then
# 扩展 ~ 符号
userOpt_install_dir="${userOpt_install_dir/#\~/$HOME}"
# 检查目录是否存在,如果不存在则创建该目录
if [ ! -d "$userOpt_install_dir" ]; then
if is_zh; then
echo "目录 $userOpt_install_dir 不存在,正在创建..."
else
echo "Directory $userOpt_install_dir does not exist. Creating..."
fi
if ! mkdir -p "$userOpt_install_dir"; then
if is_zh; then
echo "创建目录失败,请重试"
else
echo "Failed to create directory, please try again"
fi
exit 1
fi
tmp_created_install_dir="$userOpt_install_dir" # 记录临时安装目录
fi
elif existing_path=$(command -v "$binary_name" 2>/dev/null); then
if is_zh; then
info "$binary_name 已安装,更新路径: ${existing_path}"
else
info "$binary_name is already installed, updating path: ${existing_path}"
fi
userOpt_install_dir=$(dirname "$existing_path")
if [ ! -w "$userOpt_install_dir" ]; then
if is_zh; then
error_exit "目录 $userOpt_install_dir 不可写,请使用 sudo 命令运行脚本;或通过 -d 参数指定其它目录安装"
else
error_exit "Directory $userOpt_install_dir is not writable. Please run the script with sudo; or specify another dir using the -d option."
fi
fi
else
# 检查默认安装目录
if [ -d "$default_install_dir_4root" ] && [ -w "$default_install_dir_4root" ]; then
userOpt_install_dir="$default_install_dir_4root"
elif [ -d "$default_install_dir_4nonroot" ] && [ -w "$default_install_dir_4nonroot" ]; then
userOpt_install_dir="$default_install_dir_4nonroot"
else
if is_zh; then
error_exit "默认安装目录 $default_install_dir_4root 和 $default_install_dir_4nonroot 不可写,请使用 sudo 命令运行脚本;或通过 -d 参数指定其它目录安装"
else
error_exit "Default install dir $default_install_dir_4root and $default_install_dir_4nonroot is not writable. Please run the script with sudo; or specify another dir using the -d option."
fi
fi
fi
}
#
# @param $1: 下载链接
# @param $2: 保存路径(带文件名)
#
download() {
if command -v curl &>/dev/null; then
curl -sL "$1" -o "$2"
return $? # 只能单独 return
fi
if command -v wget &>/dev/null; then
# follow 是wget默认行为
wget -qO "$2" "$1"
return $?
fi
if is_zh; then
error_exit "缺乏必要的下载工具(curl或wget),无法下载文件"
else
error_exit "Missing necessary download tools (curl or wget) to download the file!"
fi
}
install() {
set_binary_version
set_arch
set_platform
set_install_dir
url="https://gitee.com/RubyMetric/chsrc/releases/download/${binary_version}/${binary_name}-${arch}-${platform}"
path_to_executable="${userOpt_install_dir}/${binary_name}"
if is_zh; then
info "下载 ${binary_name} (架构: ${arch}, 平台: ${platform}, 版本: ${binary_version}) 到 ${path_to_executable}"
else
info "Downloading ${binary_name} (arch: ${arch}, platform: ${platform}, version: ${binary_version}) to ${path_to_executable}"
fi
if download $url "$path_to_executable"; then
chmod +x "$path_to_executable"
if is_zh; then
info "🎉 安装完成,路径: $path_to_executable"
else
info "🎉 Installation completed, path: $path_to_executable"
fi
else
if is_zh; then
error_exit "下载失败,请检查网络连接和代理设置: ${url}"
else
error_exit "Download failed, please check your network connection and proxy settings: ${url}"
fi
fi
}
cleanup() {
if [ -n "$tmp_created_install_dir" ] && [ -d "$tmp_created_install_dir" ]; then
if is_zh; then
echo "清理创建的目录: $tmp_created_install_dir"
else
echo "Cleaning up created directory: $tmp_created_install_dir"
fi
rm -rf "$tmp_created_install_dir"
fi
}
trap cleanup EXIT
# main
while getopts ":hd:v:l:" option; do
case $option in
h)
userOpt_help=1
;;
d)
userOpt_install_dir=${OPTARG}
;;
v)
userOpt_version=${OPTARG}
;;
l)
userOpt_lang=${OPTARG}
;;
\?)
echo "无效的命令行选项,请使用 -h 查看帮助"
exit 1
;;
esac
done
if [[ "$userOpt_lang" != "zh" && "$userOpt_lang" != "en" ]]; then
error_exit "无效的语言选项: $userOpt_lang,支持的选项为 zh 和 en"
fi
if [ "$userOpt_help" -eq 1 ]; then
help
exit 0;
fi
install