forked from ypq123456789/TrafficCop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrafficcop.sh
551 lines (470 loc) · 21.3 KB
/
trafficcop.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
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
#!/bin/bash
WORK_DIR="/root/TrafficCop"
CONFIG_FILE="$WORK_DIR/traffic_monitor_config.txt"
LOG_FILE="$WORK_DIR/traffic_monitor.log"
SCRIPT_PATH="$WORK_DIR/traffic_monitor.sh"
LOCK_FILE="$WORK_DIR/traffic_monitor.lock"
# 设置时区为上海(东八区)
export TZ='Asia/Shanghai'
echo "-----------------------------------------------------"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 当前版本:1.0.82"| tee -a "$LOG_FILE"
# 在脚本开始时杀死所有其他 traffic_monitor.sh 进程
kill_other_instances() {
local current_pid=$$
local script_name=$(basename "\$0")
for pid in $(pgrep -f "$script_name"); do
if [ "$pid" != "$current_pid" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 终止其他脚本实例 (PID: $pid)" | tee -a "$LOG_FILE"
kill $pid
fi
done
}
migrate_files() {
# 创建新的工作目录
mkdir -p "$WORK_DIR"
# 迁移配置文件
if [ -f "/root/traffic_monitor_config.txt" ]; then
mv "/root/traffic_monitor_config.txt" "$CONFIG_FILE"
fi
# 迁移日志文件
if [ -f "/root/traffic_monitor.log" ]; then
mv "/root/traffic_monitor.log" "$LOG_FILE"
fi
# 删除旧的脚本文件,而不是迁移
if [ -f "/root/traffic_monitor.sh" ]; then
rm "/root/traffic_monitor.sh"
echo "$(date '+%Y-%m-%d %H:%M:%S') 旧的脚本文件已删除" | tee -a "$LOG_FILE"
fi
# 迁移软件包安装标志文件
if [ -f "/root/.traffic_monitor_packages_installed" ]; then
mv "/root/.traffic_monitor_packages_installed" "$WORK_DIR/.traffic_monitor_packages_installed"
fi
# 迁移其他可能存在的相关文件
for file in /root/traffic_monitor_*.txt /root/traffic_monitor_*.log; do
if [ -f "$file" ]; then
mv "$file" "$WORK_DIR/"
fi
done
# 更新 crontab 中的脚本路径
if crontab -l | grep -q "/root/traffic_monitor.sh"; then
crontab -l | sed "s|/root/traffic_monitor.sh|$SCRIPT_PATH|g" | crontab -
echo "$(date '+%Y-%m-%d %H:%M:%S') Crontab 已更新为新的脚本路径" | tee -a "$LOG_FILE"
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') 文件已迁移到新的工作目录: $WORK_DIR" | tee -a "$LOG_FILE"
}
check_and_install_packages() {
local flag_file="/$WORK_DIR/.traffic_monitor_packages_installed"
if [ -f "$flag_file" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 必要的软件包已安装" | tee -a "$LOG_FILE"
else
local packages=("vnstat" "jq" "bc" "tc")
for package in "${packages[@]}"; do
if ! command -v $package &> /dev/null; then
echo "$(date '+%Y-%m-%d %H:%M:%S') $package 未安装,正在安装..."| tee -a "$LOG_FILE"
sudo apt-get update && sudo apt-get install -y $package
echo "$(date '+%Y-%m-%d %H:%M:%S') $package 安装完成"| tee -a "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') $package 已安装"| tee -a "$LOG_FILE"
fi
done
touch "$flag_file"
fi
#echo "开始获取 vnstat 统计开始时间"| tee -a "$LOG_FILE"
# 获取 vnstat 版本
local vnstat_version=$(vnstat --version 2>&1 | head -n 1)
echo "$(date '+%Y-%m-%d %H:%M:%S') vnstat 版本: $vnstat_version"| tee -a "$LOG_FILE"
# 获取主要网络接口
local main_interface=$(ip route | grep default | sed -e 's/^.*dev \([^ ]*\).*$/\1/' | head -n 1)
echo "$(date '+%Y-%m-%d %H:%M:%S') 主要网络接口: $main_interface"| tee -a "$LOG_FILE"
# 获取 vnstat 统计开始时间
if [ -n "$main_interface" ]; then
local vnstat_json=$(vnstat -i "$main_interface" --json d)
local vnstat_start_time=$(echo "$vnstat_json" | jq -r '.interfaces[0].created.date | "\(.year)-\(.month | tostring | if length == 1 then "0" + . else . end)-\(.day | tostring | if length == 1 then "0" + . else . end)"')
if [ -n "$vnstat_start_time" ] && [ "$vnstat_start_time" != "null-null-null" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnstat 统计开始日期: $vnstat_start_time,在此之前的流量不会被纳入统计!" | tee -a "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 无法获取 vnstat 统计开始时间" | tee -a "$LOG_FILE"
echo "vnstat JSON 输出: $vnstat_json" | tee -a "$LOG_FILE"
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 无法获取主要网络接口" | tee -a "$LOG_FILE"
fi
}
# 检查配置和定时任务
check_existing_setup() {
if [ -s "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 配置已存在"| tee -a "$LOG_FILE"
if crontab -l 2>/dev/null | grep -q "$SCRIPT_PATH --run"; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 每分钟一次的定时任务已在执行。"| tee -a "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 警告:定时任务未找到,可能需要重新设置。"| tee -a "$LOG_FILE"
fi
return 0
else
return 1
fi
}
# 读取配置
read_config() {
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
return 0
else
return 1
fi
}
# 写入配置
write_config() {
cat > "$CONFIG_FILE" << EOF
TRAFFIC_MODE=$TRAFFIC_MODE
TRAFFIC_PERIOD=$TRAFFIC_PERIOD
TRAFFIC_LIMIT=$TRAFFIC_LIMIT
TRAFFIC_TOLERANCE=$TRAFFIC_TOLERANCE
PERIOD_START_DAY=${PERIOD_START_DAY:-1}
LIMIT_SPEED=${LIMIT_SPEED:-20}
MAIN_INTERFACE=$MAIN_INTERFACE
LIMIT_MODE=$LIMIT_MODE
EOF
echo "$(date '+%Y-%m-%d %H:%M:%S') 配置已更新"| tee -a "$LOG_FILE"
}
# 显示当前配置
show_current_config() {
echo "$(date '+%Y-%m-%d %H:%M:%S') 当前配置:"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 流量统计模式: $TRAFFIC_MODE"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 流量统计周期: $TRAFFIC_PERIOD"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 周期起始日: ${PERIOD_START_DAY:-1}"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 流量限制: $TRAFFIC_LIMIT GB"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 容错范围: $TRAFFIC_TOLERANCE GB"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 限速: ${LIMIT_SPEED:-20} kbit/s"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 主要网络接口: $MAIN_INTERFACE"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 限制模式: $LIMIT_MODE"| tee -a "$LOG_FILE"
}
# 检测主要网络接口
get_main_interface() {
local main_interface=$(ip route | grep default | sed -n 's/^default via [0-9.]* dev \([^ ]*\).*/\1/p' | head -n1)
if [ -z "$main_interface" ]; then
main_interface=$(ip link | grep 'state UP' | sed -n 's/^[0-9]*: \([^:]*\):.*/\1/p' | head -n1)
fi
if [ -z "$main_interface" ]; then
while true; do
echo "$(date '+%Y-%m-%d %H:%M:%S') 无法自动检测主要网络接口。"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 可用的网络接口有:"| tee -a "$LOG_FILE"
ip -o link show | sed -n 's/^[0-9]*: \([^:]*\):.*/\1/p'
read -p "请从上面的列表中选择一个网络接口: " main_interface
if [ -z "$main_interface" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 请输入一个有效的接口名称。"| tee -a "$LOG_FILE"
elif ip link show "$main_interface" > /dev/null 2>&1; then
break
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 无效的接口,请重新选择。"| tee -a "$LOG_FILE"
fi
done
else
read -p "检测到的主要网络接口是: $main_interface, 按Enter使用此接口,或输入新的接口名称: " new_interface
if [ -n "$new_interface" ]; then
if ip link show "$new_interface" > /dev/null 2>&1; then
main_interface=$new_interface
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 输入的接口无效,将使用检测到的接口: $main_interface"| tee -a "$LOG_FILE"
fi
fi
fi
echo $main_interface| tee -a "$LOG_FILE"
}
# 初始配置函数
echo "$(date '+%Y-%m-%d %H:%M:%S') 开始初始化配置"| tee -a "$LOG_FILE"
initial_config() {
echo "$(date '+%Y-%m-%d %H:%M:%S') 正在检测主要网络接口..."| tee -a "$LOG_FILE"
MAIN_INTERFACE=$(get_main_interface)
while true; do
echo "$(date '+%Y-%m-%d %H:%M:%S') 请选择流量统计模式:"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 1. 只计算出站流量"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 2. 只计算进站流量"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 3. 出进站流量都计算"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 4. 出站和进站流量只取大"| tee -a "$LOG_FILE"
read -p "请输入选择 (1-4): " mode_choice
case $mode_choice in
1) TRAFFIC_MODE="out"; break ;;
2) TRAFFIC_MODE="in"; break ;;
3) TRAFFIC_MODE="total"; break ;;
4) TRAFFIC_MODE="max"; break ;;
*) echo "无效输入,请重新选择。" ;;
esac
done
read -p "请选择流量统计周期 (m/q/y,默认为m): " period_choice
case $period_choice in
q) TRAFFIC_PERIOD="quarterly" ;;
y) TRAFFIC_PERIOD="yearly" ;;
m|"") TRAFFIC_PERIOD="monthly" ;;
*) echo "无效输入,使用默认值:monthly"; TRAFFIC_PERIOD="monthly" ;;
esac
read -p "请输入周期起始日 (1-31,默认为1): " PERIOD_START_DAY
if [[ -z "$PERIOD_START_DAY" ]]; then
PERIOD_START_DAY=1
elif ! [[ "$PERIOD_START_DAY" =~ ^[1-9]$|^[12][0-9]$|^3[01]$ ]]; then
echo "无效输入,使用默认值:1"
PERIOD_START_DAY=1
fi
while true; do
read -p "请输入流量限制 (GB): " TRAFFIC_LIMIT
if [[ "$TRAFFIC_LIMIT" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
break
else
echo "无效输入,请输入一个有效的数字。"
fi
done
while true; do
read -p "请输入容错范围 (GB): " TRAFFIC_TOLERANCE
if [[ "$TRAFFIC_TOLERANCE" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
break
else
echo "无效输入,请输入一个有效的数字。"
fi
done
while true; do
echo "$(date '+%Y-%m-%d %H:%M:%S') 请选择限制模式:"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 1. TC 模式(更灵活)"| tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 2. 关机模式(更安全)"| tee -a "$LOG_FILE"
read -p "请输入选择 (1-2): " limit_mode_choice
case $limit_mode_choice in
1)
LIMIT_MODE="tc"
read -p "请输入限速 (kbit/s,默认为20): " LIMIT_SPEED
LIMIT_SPEED=${LIMIT_SPEED:-20}
if ! [[ "$LIMIT_SPEED" =~ ^[0-9]+$ ]]; then
echo "无效输入,使用默认值:20 kbit/s"
LIMIT_SPEED=20
fi
break
;;
2)
LIMIT_MODE="shutdown"
LIMIT_SPEED="" # 关机模式不需要限速
break
;;
*) echo "无效输入,请重新选择。" ;;
esac
done
write_config
}
# 获取当前周期的起始日期
get_period_start_date() {
local current_date=$(date +%Y-%m-%d)
local current_month=$(date +%m)
local current_year=$(date +%Y)
case $TRAFFIC_PERIOD in
monthly)
if [ $(date +%d) -lt $PERIOD_START_DAY ]; then
date -d "${current_year}-${current_month}-${PERIOD_START_DAY} -1 month" +'%Y-%m-%d'
else
date -d "${current_year}-${current_month}-${PERIOD_START_DAY}" +%Y-%m-%d 2>/dev/null || date -d "${current_year}-${current_month}-01" +%Y-%m-%d
fi
;;
quarterly)
local quarter_month=$(((($(date +%m) - 1) / 3) * 3 + 1))
if [ $(date +%d) -lt $PERIOD_START_DAY ] || [ $(date +%m) -eq $quarter_month ]; then
date -d "${current_year}-${quarter_month}-${PERIOD_START_DAY} -3 month" +'%Y-%m-%d'
else
date -d "${current_year}-${quarter_month}-${PERIOD_START_DAY}" +'%Y-%m-%d' 2>/dev/null || date -d "${current_year}-${quarter_month}-01" +%Y-%m-%d
fi
;;
yearly)
if [ $(date +%d) -lt $PERIOD_START_DAY ] || [ $(date +%m) -eq 01 ]; then
date -d "${current_year}-01-${PERIOD_START_DAY} -1 year" +'%Y-%m-%d'
else
date -d "${current_year}-01-${PERIOD_START_DAY}" +'%Y-%m-%d' 2>/dev/null || date -d "${current_year}-01-01" +%Y-%m-%d
fi
;;
esac
}
# 获取周期结束日期
get_period_end_date() {
local current_date=$(date +%Y-%m-%d)
local current_month=$(date +%m)
local current_year=$(date +%Y)
case $TRAFFIC_PERIOD in
monthly)
if [ $(date +%d) -lt $PERIOD_START_DAY ]; then
date -d "${current_year}-${current_month}-${PERIOD_START_DAY} -1 day" +'%Y-%m-%d'
else
date -d "${current_year}-${current_month}-${PERIOD_START_DAY} +1 month -1 day" +'%Y-%m-%d'
fi
;;
quarterly)
local quarter_month=$(((($(date +%m) - 1) / 3) * 3 + 1))
if [ $(date +%d) -lt $PERIOD_START_DAY ] || [ $(date +%m) -eq $quarter_month ]; then
date -d "${current_year}-${quarter_month}-${PERIOD_START_DAY} +2 month -1 day" +'%Y-%m-%d'
else
date -d "${current_year}-${quarter_month}-${PERIOD_START_DAY} +5 month -1 day" +'%Y-%m-%d'
fi
;;
yearly)
if [ $(date +%d) -lt $PERIOD_START_DAY ] || [ $(date +%m) -eq 01 ]; then
date -d "${current_year}-12-31" +'%Y-%m-%d'
else
date -d "$((current_year + 1))-12-31" +'%Y-%m-%d'
fi
;;
esac
}
# 获取流量使用情况
get_traffic_usage() {
local start_date=$(get_period_start_date)
local end_date=$(get_period_end_date)
echo "$(date '+%Y-%m-%d %H:%M:%S') 周期开始日期: $start_date, 周期结束日期: $end_date" >&2
local vnstat_output=$(vnstat -i $MAIN_INTERFACE --begin "$start_date" --end "$end_date" --oneline b)
# echo "vnstat输出: $vnstat_output" >&2
local usage
case $TRAFFIC_MODE in
out)
usage=$(echo "$vnstat_output" | cut -d';' -f10)
;;
in)
usage=$(echo "$vnstat_output" | cut -d';' -f9)
;;
total)
usage=$(echo "$vnstat_output" | cut -d';' -f11)
;;
max)
local rx=$(echo "$vnstat_output" | cut -d';' -f9)
local tx=$(echo "$vnstat_output" | cut -d';' -f10)
usage=$(echo "$rx $tx" | tr ' ' '\n' | sort -rn | head -n1)
;;
esac
# echo "用量字节数: $usage" >&2
if [ -n "$usage" ]; then
# 将字节转换为 GiB,并确保结果至少有一位小数
usage=$(echo "scale=3; x=$usage/1024/1024/1024; if(x<1) print 0; x" | bc)
# echo "将字节转换为 GiB: $usage" >&2
echo $usage
else
# echo "无法获取用量字节数" >&2
echo "0.000"
fi
}
# 修改 check_and_limit_traffic 函数
check_and_limit_traffic() {
local current_usage=$(get_traffic_usage)
local limit_threshold=$(echo "$TRAFFIC_LIMIT - $TRAFFIC_TOLERANCE" | bc)
echo "$(date '+%Y-%m-%d %H:%M:%S') 当前使用流量: $current_usage GB,限制流量: $limit_threshold GB" | tee -a "$LOG_FILE"
if (( $(echo "$current_usage > $limit_threshold" | bc -l) )); then
echo "$(date '+%Y-%m-%d %H:%M:%S') 流量超出限制" | tee -a "$LOG_FILE"
if [ "$LIMIT_MODE" = "tc" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 使用 TC 模式限速" | tee -a "$LOG_FILE"
tc qdisc add dev $MAIN_INTERFACE root tbf rate ${LIMIT_SPEED}kbit burst 32kbit latency 400ms
elif [ "$LIMIT_MODE" = "shutdown" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 流量超出限制,系统将在 1 分钟后关机" | tee -a "$LOG_FILE"
shutdown -h +1 "流量超出限制,系统将在 1 分钟后关机"
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 流量正常,清除所有限制" | tee -a "$LOG_FILE"
tc qdisc del dev $MAIN_INTERFACE root 2>/dev/null
shutdown -c 2>/dev/null # 取消可能存在的关机计划
fi
}
# 检查是否需要重置限制
check_reset_limit() {
local current_date=$(date +%Y-%m-%d)
local period_start=$(get_period_start_date)
if [[ "$current_date" == "$period_start" ]]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 新的流量周期开始,重置限制"| tee -a "$LOG_FILE"
tc qdisc del dev $MAIN_INTERFACE root 2>/dev/null
fi
}
setup_crontab() {
# 删除旧的脚本任务(如果存在)
crontab -l 2>/dev/null | grep -v "$SCRIPT_PATH" | crontab -
# 添加新的脚本任务
(crontab -l 2>/dev/null; echo "* * * * * $SCRIPT_PATH --run") | crontab -
echo "$(date '+%Y-%m-%d %H:%M:%S') Crontab 已设置,每分钟运行一次"| tee -a "$LOG_FILE"
}
# 主函数
main() {
# 调用函数来杀死其他实例
kill_other_instances
# 在脚本开始时调用迁移函数
migrate_files
# 切换到工作目录
cd "$WORK_DIR" || exit 1
# 创建锁文件(如果不存在)
touch "${LOCK_FILE}"
# 尝试获取文件锁
exec 9>"${LOCK_FILE}"
if ! flock -n 9; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 另一个脚本实例正在运行,退出。" | tee -a "$LOG_FILE"
exit 1
fi
# 检查是否以 --run 模式运行
if [ "\$1" = "--run" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 正在以自动化模式运行" | tee -a "$LOG_FILE"
if read_config; then
check_reset_limit
check_and_limit_traffic
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 配置文件读取失败,请检查配置" | tee -a "$LOG_FILE"
fi
return
fi
# 非 --run 模式下的操作
# 首先检查并安装必要的软件包
check_and_install_packages
if check_existing_setup; then
read_config
show_current_config
echo "$(date '+%Y-%m-%d %H:%M:%S') 是否需要修改配置?(y/n): 5秒内按任意键修改配置,否则保持现有配置" | tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 开始等待用户输入..." | tee -a "$LOG_FILE"
start_time=$(date +%s.%N)
if read -t 5 -n 1 modify_config; then
end_time=$(date +%s.%N)
duration=$(echo "$end_time - $start_time" | bc)
echo "" # 换行
echo "$(date '+%Y-%m-%d %H:%M:%S') 收到用户输入: '${modify_config}' (ASCII: $(printf '%d' "'$modify_config" 2>/dev/null || echo "N/A"))" | tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 等待时间: $duration 秒" | tee -a "$LOG_FILE"
if [[ $duration < 0.1 ]]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 警告:输入时间过短,可能是自动输入" | tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 忽略此输入,保持现有配置。" | tee -a "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 开始修改配置..." | tee -a "$LOG_FILE"
initial_config
setup_crontab
echo "$(date '+%Y-%m-%d %H:%M:%S') 配置已更新,脚本将每分钟自动运行一次" | tee -a "$LOG_FILE"
fi
else
end_time=$(date +%s.%N)
duration=$(echo "$end_time - $start_time" | bc)
echo "" # 换行
echo "$(date '+%Y-%m-%d %H:%M:%S') 等待超时,无用户输入" | tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 等待时间: $duration 秒" | tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 保持现有配置。" | tee -a "$LOG_FILE"
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 开始初始化配置..." | tee -a "$LOG_FILE"
initial_config
setup_crontab
echo "$(date '+%Y-%m-%d %H:%M:%S') 初始配置完成,脚本将每分钟自动运行一次" | tee -a "$LOG_FILE"
fi
# 显示当前流量使用情况和限制状态
if read_config; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 当前流量使用情况:" | tee -a "$LOG_FILE"
local current_usage=$(get_traffic_usage)
#echo "Debug: Current usage from get_traffic_usage: $current_usage" | tee -a "$LOG_FILE"
if [ "$current_usage" != "0" ]; then
local start_date=$(get_period_start_date)
echo "$(date '+%Y-%m-%d %H:%M:%S') 当前统计周期: $TRAFFIC_PERIOD (从 $start_date 开始)" | tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 统计模式: $TRAFFIC_MODE" | tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 当前使用流量: $current_usage GB" | tee -a "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') 检查并限制流量:" | tee -a "$LOG_FILE"
check_and_limit_traffic
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 无法获取流量数据,请检查 vnstat 配置" | tee -a "$LOG_FILE"
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 配置文件读取失败,请检查配置" | tee -a "$LOG_FILE"
fi
# 确保脚本退出时释放锁
trap 'flock -u 9; rm -f ${LOCK_FILE}' EXIT
}
# 执行主函数
main "$@"
echo "-----------------------------------------------------"| tee -a "$LOG_FILE"