-
Notifications
You must be signed in to change notification settings - Fork 356
/
install.sh
434 lines (381 loc) · 10.8 KB
/
install.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
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
422
423
424
425
426
427
428
429
430
431
432
433
434
#!/bin/bash
author=233boy
# github=https://github.com/233boy/sing-box
# bash fonts colors
red='\e[31m'
yellow='\e[33m'
gray='\e[90m'
green='\e[92m'
blue='\e[94m'
magenta='\e[95m'
cyan='\e[96m'
none='\e[0m'
_red() { echo -e ${red}$@${none}; }
_blue() { echo -e ${blue}$@${none}; }
_cyan() { echo -e ${cyan}$@${none}; }
_green() { echo -e ${green}$@${none}; }
_yellow() { echo -e ${yellow}$@${none}; }
_magenta() { echo -e ${magenta}$@${none}; }
_red_bg() { echo -e "\e[41m$@${none}"; }
is_err=$(_red_bg 错误!)
is_warn=$(_red_bg 警告!)
err() {
echo -e "\n$is_err $@\n" && exit 1
}
warn() {
echo -e "\n$is_warn $@\n"
}
# root
[[ $EUID != 0 ]] && err "当前非 ${yellow}ROOT用户.${none}"
# yum or apt-get, ubuntu/debian/centos
cmd=$(type -P apt-get || type -P yum)
[[ ! $cmd ]] && err "此脚本仅支持 ${yellow}(Ubuntu or Debian or CentOS)${none}."
# systemd
[[ ! $(type -P systemctl) ]] && {
err "此系统缺少 ${yellow}(systemctl)${none}, 请尝试执行:${yellow} ${cmd} update -y;${cmd} install systemd -y ${none}来修复此错误."
}
# wget installed or none
is_wget=$(type -P wget)
# x64
case $(uname -m) in
amd64 | x86_64)
is_arch=amd64
;;
*aarch64* | *armv8*)
is_arch=arm64
;;
*)
err "此脚本仅支持 64 位系统..."
;;
esac
is_core=sing-box
is_core_name=sing-box
is_core_dir=/etc/$is_core
is_core_bin=$is_core_dir/bin/$is_core
is_core_repo=SagerNet/$is_core
is_conf_dir=$is_core_dir/conf
is_log_dir=/var/log/$is_core
is_sh_bin=/usr/local/bin/$is_core
is_sh_dir=$is_core_dir/sh
is_sh_repo=$author/$is_core
is_pkg="wget tar"
is_config_json=$is_core_dir/config.json
tmp_var_lists=(
tmpcore
tmpsh
tmpjq
is_core_ok
is_sh_ok
is_jq_ok
is_pkg_ok
)
# tmp dir
tmpdir=$(mktemp -u)
[[ ! $tmpdir ]] && {
tmpdir=/tmp/tmp-$RANDOM
}
# set up var
for i in ${tmp_var_lists[*]}; do
export $i=$tmpdir/$i
done
# load bash script.
load() {
. $is_sh_dir/src/$1
}
# wget add --no-check-certificate
_wget() {
[[ $proxy ]] && export https_proxy=$proxy
wget --no-check-certificate $*
}
# print a mesage
msg() {
case $1 in
warn)
local color=$yellow
;;
err)
local color=$red
;;
ok)
local color=$green
;;
esac
echo -e "${color}$(date +'%T')${none}) ${2}"
}
# show help msg
show_help() {
echo -e "Usage: $0 [-f xxx | -l | -p xxx | -v xxx | -h]"
echo -e " -f, --core-file <path> 自定义 $is_core_name 文件路径, e.g., -f /root/$is_core-linux-amd64.tar.gz"
echo -e " -l, --local-install 本地获取安装脚本, 使用当前目录"
echo -e " -p, --proxy <addr> 使用代理下载, e.g., -p http://127.0.0.1:2333 or -p socks5://127.0.0.1:2333"
echo -e " -v, --core-version <ver> 自定义 $is_core_name 版本, e.g., -v v1.8.13"
echo -e " -h, --help 显示此帮助界面\n"
exit 0
}
# install dependent pkg
install_pkg() {
cmd_not_found=
for i in $*; do
[[ ! $(type -P $i) ]] && cmd_not_found="$cmd_not_found,$i"
done
if [[ $cmd_not_found ]]; then
pkg=$(echo $cmd_not_found | sed 's/,/ /g')
msg warn "安装依赖包 >${pkg}"
$cmd install -y $pkg &>/dev/null
if [[ $? != 0 ]]; then
[[ $cmd =~ yum ]] && yum install epel-release -y &>/dev/null
$cmd update -y &>/dev/null
$cmd install -y $pkg &>/dev/null
[[ $? == 0 ]] && >$is_pkg_ok
else
>$is_pkg_ok
fi
else
>$is_pkg_ok
fi
}
# download file
download() {
case $1 in
core)
[[ ! $is_core_ver ]] && is_core_ver=$(_wget -qO- "https://api.github.com/repos/${is_core_repo}/releases/latest?v=$RANDOM" | grep tag_name | egrep -o 'v([0-9.]+)')
[[ $is_core_ver ]] && link="https://github.com/${is_core_repo}/releases/download/${is_core_ver}/${is_core}-${is_core_ver:1}-linux-${is_arch}.tar.gz"
name=$is_core_name
tmpfile=$tmpcore
is_ok=$is_core_ok
;;
sh)
link=https://github.com/${is_sh_repo}/releases/latest/download/code.tar.gz
name="$is_core_name 脚本"
tmpfile=$tmpsh
is_ok=$is_sh_ok
;;
jq)
link=https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-$is_arch
name="jq"
tmpfile=$tmpjq
is_ok=$is_jq_ok
;;
esac
[[ $link ]] && {
msg warn "下载 ${name} > ${link}"
if _wget -t 3 -q -c $link -O $tmpfile; then
mv -f $tmpfile $is_ok
fi
}
}
# get server ip
get_ip() {
export "$(_wget -4 -qO- https://one.one.one.one/cdn-cgi/trace | grep ip=)" &>/dev/null
[[ -z $ip ]] && export "$(_wget -6 -qO- https://one.one.one.one/cdn-cgi/trace | grep ip=)" &>/dev/null
}
# check background tasks status
check_status() {
# dependent pkg install fail
[[ ! -f $is_pkg_ok ]] && {
msg err "安装依赖包失败"
is_fail=1
}
# download file status
if [[ $is_wget ]]; then
[[ ! -f $is_core_ok ]] && {
msg err "下载 ${is_core_name} 失败"
is_fail=1
}
[[ ! -f $is_sh_ok ]] && {
msg err "下载 ${is_core_name} 脚本失败"
is_fail=1
}
[[ ! -f $is_jq_ok ]] && {
msg err "下载 jq 失败"
is_fail=1
}
else
[[ ! $is_fail ]] && {
is_wget=1
[[ ! $is_core_file ]] && download core &
[[ ! $local_install ]] && download sh &
[[ $jq_not_found ]] && download jq &
get_ip
wait
check_status
}
fi
# found fail status, remove tmp dir and exit.
[[ $is_fail ]] && {
exit_and_del_tmpdir
}
}
# parameters check
pass_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-f | --core-file)
[[ -z $2 ]] && {
err "($1) 缺少必需参数, 正确使用示例: [$1 /root/$is_core-linux-amd64.tar.gz]"
} || [[ ! -f $2 ]] && {
err "($2) 不是一个常规的文件."
}
is_core_file=$2
shift 2
;;
-l | --local-install)
[[ ! -f ${PWD}/src/core.sh || ! -f ${PWD}/$is_core.sh ]] && {
err "当前目录 (${PWD}) 非完整的脚本目录."
}
local_install=1
shift 1
;;
-p | --proxy)
[[ -z $2 ]] && {
err "($1) 缺少必需参数, 正确使用示例: [$1 http://127.0.0.1:2333 or -p socks5://127.0.0.1:2333]"
}
proxy=$2
shift 2
;;
-v | --core-version)
[[ -z $2 ]] && {
err "($1) 缺少必需参数, 正确使用示例: [$1 v1.8.13]"
}
is_core_ver=v${2//v/}
shift 2
;;
-h | --help)
show_help
;;
*)
echo -e "\n${is_err} ($@) 为未知参数...\n"
show_help
;;
esac
done
[[ $is_core_ver && $is_core_file ]] && {
err "无法同时自定义 ${is_core_name} 版本和 ${is_core_name} 文件."
}
}
# exit and remove tmpdir
exit_and_del_tmpdir() {
rm -rf $tmpdir
[[ ! $1 ]] && {
msg err "哦豁.."
msg err "安装过程出现错误..."
echo -e "反馈问题) https://github.com/${is_sh_repo}/issues"
echo
exit 1
}
exit
}
# main
main() {
# check old version
[[ -f $is_sh_bin && -d $is_core_dir/bin && -d $is_sh_dir && -d $is_conf_dir ]] && {
err "检测到脚本已安装, 如需重装请使用${green} ${is_core} reinstall ${none}命令."
}
# check parameters
[[ $# -gt 0 ]] && pass_args $@
# show welcome msg
clear
echo
echo "........... $is_core_name script by $author .........."
echo
# start installing...
msg warn "开始安装..."
[[ $is_core_ver ]] && msg warn "${is_core_name} 版本: ${yellow}$is_core_ver${none}"
[[ $proxy ]] && msg warn "使用代理: ${yellow}$proxy${none}"
# create tmpdir
mkdir -p $tmpdir
# if is_core_file, copy file
[[ $is_core_file ]] && {
cp -f $is_core_file $is_core_ok
msg warn "${yellow}${is_core_name} 文件使用 > $is_core_file${none}"
}
# local dir install sh script
[[ $local_install ]] && {
>$is_sh_ok
msg warn "${yellow}本地获取安装脚本 > $PWD ${none}"
}
timedatectl set-ntp true &>/dev/null
[[ $? != 0 ]] && {
is_ntp_on=1
}
# install dependent pkg
install_pkg $is_pkg &
# jq
if [[ $(type -P jq) ]]; then
>$is_jq_ok
else
jq_not_found=1
fi
# if wget installed. download core, sh, jq, get ip
[[ $is_wget ]] && {
[[ ! $is_core_file ]] && download core &
[[ ! $local_install ]] && download sh &
[[ $jq_not_found ]] && download jq &
get_ip
}
# waiting for background tasks is done
wait
# check background tasks status
check_status
# test $is_core_file
if [[ $is_core_file ]]; then
mkdir -p $tmpdir/testzip
tar zxf $is_core_ok --strip-components 1 -C $tmpdir/testzip &>/dev/null
[[ $? != 0 ]] && {
msg err "${is_core_name} 文件无法通过测试."
exit_and_del_tmpdir
}
[[ ! -f $tmpdir/testzip/$is_core ]] && {
msg err "${is_core_name} 文件无法通过测试."
exit_and_del_tmpdir
}
fi
# get server ip.
[[ ! $ip ]] && {
msg err "获取服务器 IP 失败."
exit_and_del_tmpdir
}
# create sh dir...
mkdir -p $is_sh_dir
# copy sh file or unzip sh zip file.
if [[ $local_install ]]; then
cp -rf $PWD/* $is_sh_dir
else
tar zxf $is_sh_ok -C $is_sh_dir
fi
# create core bin dir
mkdir -p $is_core_dir/bin
# copy core file or unzip core zip file
if [[ $is_core_file ]]; then
cp -rf $tmpdir/testzip/* $is_core_dir/bin
else
tar zxf $is_core_ok --strip-components 1 -C $is_core_dir/bin
fi
# add alias
echo "alias sb=$is_sh_bin" >>/root/.bashrc
echo "alias $is_core=$is_sh_bin" >>/root/.bashrc
# core command
ln -sf $is_sh_dir/$is_core.sh $is_sh_bin
ln -sf $is_sh_dir/$is_core.sh ${is_sh_bin/$is_core/sb}
# jq
[[ $jq_not_found ]] && mv -f $is_jq_ok /usr/bin/jq
# chmod
chmod +x $is_core_bin $is_sh_bin /usr/bin/jq ${is_sh_bin/$is_core/sb}
# create log dir
mkdir -p $is_log_dir
# show a tips msg
msg ok "生成配置文件..."
# create systemd service
load systemd.sh
is_new_install=1
install_service $is_core &>/dev/null
# create condf dir
mkdir -p $is_conf_dir
load core.sh
# create a reality config
add reality
# remove tmp dir and exit.
exit_and_del_tmpdir ok
}
# start.
main $@